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 | |
| parent | b99057bc15e72397f3951ddee28d4db481caad02 (diff) | |
| download | ECTester-8dda00c46e73f2a44e7c387a6b4e86055ffecea2.tar.gz ECTester-8dda00c46e73f2a44e7c387a6b4e86055ffecea2.tar.zst ECTester-8dda00c46e73f2a44e7c387a6b4e86055ffecea2.zip | |
| -rw-r--r-- | util/plot_dh.ipynb | 214 | ||||
| -rw-r--r-- | util/plot_dsa.ipynb | 224 | ||||
| -rw-r--r-- | util/plot_gen.ipynb | 155 | ||||
| -rw-r--r-- | util/utils.py | 15 |
4 files changed, 351 insertions, 257 deletions
diff --git a/util/plot_dh.ipynb b/util/plot_dh.ipynb index 4d4edbc..2e82292 100644 --- a/util/plot_dh.ipynb +++ b/util/plot_dh.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Analysis of key generation data" + "# Analysis of key agreement data" ] }, { @@ -12,13 +12,13 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:51:29.892989Z", - "start_time": "2019-03-17T19:51:29.557783Z" + "end_time": "2019-03-18T18:35:11.337869Z", + "start_time": "2019-03-18T18:35:11.331608Z" } }, "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", @@ -48,8 +48,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:57:52.012826Z", - "start_time": "2019-03-17T19:57:52.008374Z" + "end_time": "2019-03-18T18:35:28.957529Z", + "start_time": "2019-03-18T18:35:28.952399Z" } }, "outputs": [], @@ -57,6 +57,14 @@ "# File name with output from ECTesterReader or ECTesterStandalone ECDH.\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", + "time_unit = \"milli\"\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", @@ -94,8 +102,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:51:36.973070Z", - "start_time": "2019-03-17T19:51:36.967369Z" + "end_time": "2019-03-18T18:35:30.394517Z", + "start_time": "2019-03-18T18:35:29.499890Z" } }, "outputs": [], @@ -111,20 +119,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:51:39.208449Z", - "start_time": "2019-03-17T19:51:37.430702Z" - } - }, - "outputs": [], - "source": [ + " norm = colors.Normalize()\n", + "\n", "# Read the header line.\n", "\n", "with open(fname, \"r\") as f:\n", @@ -140,31 +136,14 @@ "data = np.genfromtxt(fname, delimiter=\";\", skip_header=1, converters={2: unhexlify, 3: hx, 4: hx},\n", " dtype=np.dtype([(\"index\", \"u4\"), (\"time\", \"u4\"), (\"pub\", \"O\"), (\"priv\", \"O\"), (\"secret\", \"O\")]))\n", "\n", - "time_unit = \"ms\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "ExecuteTime": { - "end_time": "2019-03-17T19:57:56.363502Z", - "start_time": "2019-03-17T19:57:56.331005Z" - } - }, - "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 time_unit == \"ms\":\n", - " time_unit = r\"$\\mu s$\"\n", - " np.floor_divide(data[\"time\"], 1000, out=data[\"time\"])\n", + "# Setup the data\n", "\n", + "orig_time_unit = header_names[1].split(\"[\")[1][:-1]\n", + "time_disp_unit = time_scale(data[\"time\"], orig_time_unit, time_unit, scaling_factor)\n", "\n", "# Trim times\n", "quant_low_bound = trim_low if 0 <= trim_low <= 1 else 0.01\n", @@ -189,6 +168,7 @@ "min_time = description.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", @@ -231,8 +211,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:57:59.534102Z", - "start_time": "2019-03-17T19:57:59.507172Z" + "end_time": "2019-03-18T18:35:31.158217Z", + "start_time": "2019-03-18T18:35:31.144280Z" } }, "outputs": [], @@ -259,14 +239,14 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:58:00.833677Z", - "start_time": "2019-03-17T19:58:00.827736Z" + "end_time": "2019-03-18T18:35:32.593550Z", + "start_time": "2019-03-18T18:35:32.588147Z" } }, "outputs": [], "source": [ "tbl = [(quant_low_bound, \"0.25\", \"0.5\", \"0.75\", quant_high_bound),\n", - " list(map(lambda x: \"{} {}\".format(x, time_unit), quantiles))]\n", + " list(map(lambda x: \"{} {}\".format(x, time_disp_unit), quantiles))]\n", "display(HTML(tabulate.tabulate(tbl, tablefmt=\"html\")))" ] }, @@ -282,8 +262,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:58:01.954382Z", - "start_time": "2019-03-17T19:58:01.947339Z" + "end_time": "2019-03-18T18:35:33.252850Z", + "start_time": "2019-03-18T18:35:33.245928Z" } }, "outputs": [], @@ -304,7 +284,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." ] }, { @@ -312,8 +293,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:58:03.641387Z", - "start_time": "2019-03-17T19:58:03.572612Z" + "end_time": "2019-03-18T18:35:34.581846Z", + "start_time": "2019-03-18T18:35:34.472065Z" } }, "outputs": [], @@ -329,7 +310,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(\"key agreement time ({})\".format(time_unit))\n", + "axe_private.set_ylabel(\"key agreement time ({})\".format(time_disp_unit))\n", "fig_private.colorbar(im, ax=axe_private)\n", "\n", "del priv_msb" @@ -339,7 +320,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." ] }, { @@ -347,8 +331,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:58:07.768683Z", - "start_time": "2019-03-17T19:58:06.938237Z" + "end_time": "2019-03-18T18:35:39.673526Z", + "start_time": "2019-03-18T18:35:38.253945Z" } }, "outputs": [], @@ -362,7 +346,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(\"key agreement time ({})\".format(time_unit))\n", + "axe_priv_hist.set_ylabel(\"key agreement time ({})\".format(time_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", @@ -392,8 +376,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:58:17.986917Z", - "start_time": "2019-03-17T19:58:11.101449Z" + "end_time": "2019-03-18T18:35:51.604298Z", + "start_time": "2019-03-18T18:35:40.980632Z" } }, "outputs": [], @@ -401,8 +385,8 @@ "fig_ka_hist = plt.figure(figsize=(10.5, 8), dpi=90)\n", "axe_hist_full = fig_ka_hist.add_subplot(2, 1, 1)\n", "axe_hist_trim = fig_ka_hist.add_subplot(2, 1, 2)\n", - "plot_hist(axe_hist_full, data[\"time\"], \"key agreement time ({})\".format(time_unit), log_scale, hist_size_time);\n", - "plot_hist(axe_hist_trim, data_trimmed[\"time\"], \"key agreement time ({})\".format(time_unit), log_scale, hist_size_time_trim);" + "plot_hist(axe_hist_full, data[\"time\"], \"key agreement time ({})\".format(time_disp_unit), log_scale, hist_size_time);\n", + "plot_hist(axe_hist_trim, data_trimmed[\"time\"], \"key agreement time ({})\".format(time_disp_unit), log_scale, hist_size_time_trim);" ] }, { @@ -417,8 +401,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:51:57.934476Z", - "start_time": "2019-03-17T19:51:57.877729Z" + "end_time": "2019-03-18T18:36:00.467782Z", + "start_time": "2019-03-18T18:36:00.418942Z" } }, "outputs": [], @@ -433,7 +417,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(\"key agreement time ({})\".format(time_unit))\n", + "axe_avg.set_ylabel(\"key agreement time ({})\".format(time_disp_unit))\n", "axe_avg.set_xlabel(\"index\")\n", "axe_avg.legend(loc=\"best\")\n", "\n", @@ -444,7 +428,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]." ] }, { @@ -452,8 +437,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:51:58.466578Z", - "start_time": "2019-03-17T19:51:57.937797Z" + "end_time": "2019-03-18T18:36:02.558769Z", + "start_time": "2019-03-18T18:36:02.216115Z" }, "hide_input": false }, @@ -474,7 +459,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Public key coordinate MSB and LSB histograms" + "### 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." ] }, { @@ -482,42 +468,37 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:52:21.184705Z", - "start_time": "2019-03-17T19:52:20.589707Z" + "end_time": "2019-03-18T18:36:04.445752Z", + "start_time": "2019-03-18T18:36:04.317542Z" } }, "outputs": [], "source": [ - "def _split(xy):\n", - " x = int.from_bytes(xy[1:byte_size + 1], byteorder=\"big\")\n", - " y = int.from_bytes(xy[1 + byte_size:], byteorder=\"big\")\n", - " return (x, y)\n", - "\n", - "pub_coords = np.array(list(map(_split, data[\"pub\"])), dtype=np.dtype(\"O\"))\n", - "xs = pub_coords[...,0]\n", - "ys = pub_coords[...,1]\n", - "fig_pub_hists = plt.figure(figsize=(10.5, 14), dpi=90)\n", + "fig_bl = plt.figure(figsize=(10.5, 12), dpi=90)\n", + "gs = gridspec.GridSpec(2, 1, height_ratios=[2.5, 1])\n", + "axe_bl_heat = fig_bl.add_subplot(gs[0])\n", + "axe_bl_hist = fig_bl.add_subplot(gs[1], sharex=axe_bl_heat)\n", + "bl_data = np.array(list(map(lambda x: x.bit_length(), data_trimmed[\"priv\"])), dtype=np.dtype(\"u2\"))\n", "\n", - "def _plot_coord(data, name, offset):\n", - " axe_msb_pub_hist = fig_pub_hists.add_subplot(4, 1, offset)\n", - " axe_lsb_pub_hist = fig_pub_hists.add_subplot(4, 1, offset + 1)\n", - " pub_msb = np.array(list(map(lambda x: x >> (bit_size - 8), data)))\n", - " pub_lsb = np.array(list(map(lambda x: x & 0xff, data)))\n", - " plot_hist(axe_msb_pub_hist, pub_msb, \"{} coordinate MSB\".format(name), log_scale)\n", - " plot_hist(axe_lsb_pub_hist, pub_lsb, \"{} coordinate LSB\".format(name), log_scale)\n", - " del pub_msb, pub_lsb\n", + "h, xe, ye = np.histogram2d(bl_data, data_trimmed[\"time\"], bins=[max(bl_data) - min(bl_data), hist_size_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(\"key agreement time ({})\".format(time_disp_unit))\n", "\n", - "_plot_coord(xs, \"X\", 1)\n", - "_plot_coord(ys, \"Y\", 3)\n", + "plot_hist(axe_bl_hist, bl_data, \"Private key bit length\", log_scale, align=\"right\")\n", + "fig_bl.colorbar(im, ax=[axe_bl_heat, axe_bl_hist])\n", "\n", - "del pub_coords, xs, ys" + "del bl_data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Private key bit length histogram" + "## 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." ] }, { @@ -525,27 +506,14 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:52:07.657216Z", - "start_time": "2019-03-17T19:52:07.549731Z" + "end_time": "2019-03-18T18:36:15.492599Z", + "start_time": "2019-03-18T18:36:12.008827Z" } }, "outputs": [], "source": [ - "fig_bl = plt.figure(figsize=(10.5, 12), dpi=90)\n", - "gs = gridspec.GridSpec(2, 1, height_ratios=[2.5, 1])\n", - "axe_bl_heat = fig_bl.add_subplot(gs[0])\n", - "axe_bl_hist = fig_bl.add_subplot(gs[1], sharex=axe_bl_heat)\n", - "bl_data = np.array(list(map(lambda x: x.bit_length(), data_trimmed[\"priv\"])), dtype=np.dtype(\"u2\"))\n", - "\n", - "h, xe, ye = np.histogram2d(bl_data, data_trimmed[\"time\"], bins=[max(bl_data) - min(bl_data), hist_size_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(\"key agreement time ({})\".format(time_unit))\n", - "\n", - "plot_hist(axe_bl_hist, bl_data, \"Private key bit length\", log_scale, align=\"right\")\n", - "fig_bl.colorbar(im, ax=[axe_bl_heat, axe_bl_hist])\n", - "\n", - "del bl_data" + "p_str = input(\"The prime specifying the finite field:\")\n", + "p = int(p_str, 16) if p_str.startswith(\"0x\") else int(p_str)" ] }, { @@ -553,13 +521,35 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "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": [ + "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": "954c1f99782e402895d668a42553e22f", - "lastKernelId": "0b8e59f0-d640-4f72-ae7f-1b327e75910b" + "lastCommId": "73e8d2ab400746298b234c8983722e8e", + "lastKernelId": "cedfe41c-66b9-4611-ad6f-ab448422bbd2" }, "hide_input": false, "kernelspec": { diff --git a/util/plot_dsa.ipynb b/util/plot_dsa.ipynb index dbfb38b..503bde8 100644 --- a/util/plot_dsa.ipynb +++ b/util/plot_dsa.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Analysis of key generation data" + "# Analysis of signature data" ] }, { @@ -12,13 +12,13 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:00:25.518989Z", - "start_time": "2019-03-17T23:00:24.501601Z" + "end_time": "2019-03-18T18:08:10.526799Z", + "start_time": "2019-03-18T18:08:10.073972Z" } }, "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", @@ -48,8 +48,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:06:29.704432Z", - "start_time": "2019-03-17T23:06:29.694540Z" + "end_time": "2019-03-18T18:15:54.067732Z", + "start_time": "2019-03-18T18:15:54.063679Z" } }, "outputs": [], @@ -57,8 +57,17 @@ "# File name with output from ECTesterReader or ECTesterStandalone signatures.\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", + "sign_unit = \"milli\"\n", + "verify_unit = \"milli\"\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", + "skip_first = 100\n", "\n", "# Whether to plot things in logarithmic scale or not.\n", "log_scale = False\n", @@ -94,8 +103,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:06:30.551732Z", - "start_time": "2019-03-17T23:06:30.545202Z" + "end_time": "2019-03-18T18:15:55.985799Z", + "start_time": "2019-03-18T18:15:55.495414Z" } }, "outputs": [], @@ -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-17T23:00:38.023486Z", - "start_time": "2019-03-17T23:00:27.178465Z" - } - }, - "outputs": [], - "source": [ + " norm = colors.Normalize()\n", + "\n", "# Read the header line.\n", "\n", "with open(fname, \"r\") as f:\n", @@ -142,39 +139,18 @@ " 8: lambda b: bool(int(b))},\n", " dtype=np.dtype([(\"index\", \"u4\"), (\"sign_time\", \"u4\"), (\"verify_time\", \"u4\"),\n", " (\"data\", \"O\"), (\"pub\", \"O\"), (\"priv\", \"O\"), (\"signature\", \"O\"),\n", - " (\"nonce\", \"O\"), (\"valid\", \"b\")]))\n", - "\n", - " \n", - "sign_unit = \"ms\"\n", - "verify_unit = \"ms\"\n", - "# Setup the datatrimmed = False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "ExecuteTime": { - "end_time": "2019-03-17T23:00:38.465677Z", - "start_time": "2019-03-17T23:00:38.025692Z" - } - }, - "outputs": [], - "source": [ - "# Setup the data\n", - "\n", + " (\"nonce\", \"O\"), (\"valid\", \"b\")]))\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 sign_unit == \"ms\":\n", - " sign_unit = r\"$\\mu s$\"\n", - " np.floor_divide(data[\"sign_time\"], 1000, out=data[\"sign_time\"])\n", + "# Setup the data\n", "\n", - "if header_names[2].endswith(\"[nano]\") and verify_unit == \"ms\":\n", - " verify_unit = r\"$\\mu s$\"\n", - " np.floor_divide(data[\"verify_time\"], 1000, out=data[\"verify_time\"])\n", + "# Convert time data\n", + "orig_sign_unit = header_names[1].split(\"[\")[1][:-1]\n", + "orig_verify_unit = header_names[2].split(\"[\")[1][:-1]\n", + "sign_disp_unit = time_scale(data[\"sign_time\"], orig_sign_unit, sign_unit, scaling_factor)\n", + "verify_disp_unit = time_scale(data[\"verify_time\"], orig_verify_unit, verify_unit, scaling_factor)\n", "\n", "# Trim times\n", "quant_low_bound = trim_low if 0 <= trim_low <= 1 else 0.01\n", @@ -242,8 +218,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:00:39.540701Z", - "start_time": "2019-03-17T23:00:39.511019Z" + "end_time": "2019-03-18T18:15:57.175564Z", + "start_time": "2019-03-18T18:15:57.161611Z" } }, "outputs": [], @@ -270,14 +246,14 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:00:40.974497Z", - "start_time": "2019-03-17T23:00:40.953755Z" + "end_time": "2019-03-18T18:15:58.257820Z", + "start_time": "2019-03-18T18:15:58.254036Z" } }, "outputs": [], "source": [ "tbl = [(quant_low_bound, \"0.25\", \"0.5\", \"0.75\", quant_high_bound),\n", - " list(map(lambda x: \"{} {}\".format(x, sign_unit), quantiles_sign))]\n", + " list(map(lambda x: \"{} {}\".format(x, sign_disp_unit), quantiles_sign))]\n", "display(HTML(tabulate.tabulate(tbl, tablefmt=\"html\")))" ] }, @@ -293,8 +269,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:00:41.961541Z", - "start_time": "2019-03-17T23:00:41.949385Z" + "end_time": "2019-03-18T18:15:58.917927Z", + "start_time": "2019-03-18T18:15:58.909693Z" } }, "outputs": [], @@ -313,7 +289,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Nonce MSB vs signature time heatmap" + "### Nonce MSB vs signature time heatmap\n", + "The heatmap should show uncorrelated variables." ] }, { @@ -321,8 +298,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:06:34.030472Z", - "start_time": "2019-03-17T23:06:33.761991Z" + "end_time": "2019-03-18T18:15:59.977656Z", + "start_time": "2019-03-18T18:15:59.926337Z" } }, "outputs": [], @@ -338,7 +315,7 @@ "im = axe_nonce.imshow(heatmap.T, extent=extent, aspect=\"auto\", cmap=cmap, origin=\"low\",\n", " interpolation=\"nearest\", norm=norm)\n", "axe_nonce.set_xlabel(\"nonce key MSB value\")\n", - "axe_nonce.set_ylabel(\"signature time ({})\".format(sign_unit))\n", + "axe_nonce.set_ylabel(\"signature time ({})\".format(sign_disp_unit))\n", "fig_nonce.colorbar(im, ax=axe_nonce)\n", "\n", "del nonce_msb" @@ -348,7 +325,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Nonce Hamming Weight vs signature time heatmap" + "### Nonce Hamming Weight vs signature time heatmap\n", + "The heatmap should show uncorrelated variables.\n", + "\n", + "Also contains a nonce Hamming Weight histogram, which should be binomially distributed." ] }, { @@ -356,8 +336,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:05:26.804859Z", - "start_time": "2019-03-17T23:05:18.214110Z" + "end_time": "2019-03-18T18:16:01.977710Z", + "start_time": "2019-03-18T18:16:01.717704Z" } }, "outputs": [], @@ -371,7 +351,7 @@ "im = axe_nonce_hist.imshow(h.T, origin=\"low\", cmap=cmap, aspect=\"auto\", extent=[xe[0], xe[-1], ye[0], ye[-1]], norm=norm)\n", "axe_nonce_hist.axvline(x=bit_size//2, alpha=0.7, linestyle=\"dotted\", color=\"white\", label=str(bit_size//2) + \" bits\")\n", "axe_nonce_hist.set_xlabel(\"nonce Hamming weight\")\n", - "axe_nonce_hist.set_ylabel(\"signature time ({})\".format(sign_unit))\n", + "axe_nonce_hist.set_ylabel(\"signature time ({})\".format(sign_disp_unit))\n", "axe_nonce_hist.legend(loc=\"best\")\n", "\n", "plot_hist(axe_nonce_hist_hw, nonce_hw, \"nonce Hamming weight\", log_scale, True, True)\n", @@ -401,8 +381,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:05:32.395983Z", - "start_time": "2019-03-17T23:05:32.068823Z" + "end_time": "2019-03-18T18:16:03.232728Z", + "start_time": "2019-03-18T18:16:03.134237Z" } }, "outputs": [], @@ -410,8 +390,8 @@ "fig_sig_hist = plt.figure(figsize=(10.5, 8), dpi=90)\n", "axe_hist_full = fig_sig_hist.add_subplot(2, 1, 1)\n", "axe_hist_trim = fig_sig_hist.add_subplot(2, 1, 2)\n", - "plot_hist(axe_hist_full, data[\"sign_time\"], \"signature time ({})\".format(sign_unit), log_scale, hist_size_sign_time);\n", - "plot_hist(axe_hist_trim, data_trimmed[\"sign_time\"], \"signature time ({})\".format(sign_unit), log_scale, hist_size_sign_time_trim);" + "plot_hist(axe_hist_full, data[\"sign_time\"], \"signature time ({})\".format(sign_disp_unit), log_scale, hist_size_sign_time);\n", + "plot_hist(axe_hist_trim, data_trimmed[\"sign_time\"], \"signature time ({})\".format(sign_disp_unit), log_scale, hist_size_sign_time_trim);" ] }, { @@ -426,15 +406,15 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:05:33.358613Z", - "start_time": "2019-03-17T23:05:32.963791Z" + "end_time": "2019-03-18T18:16:04.380116Z", + "start_time": "2019-03-18T18:16:04.227481Z" } }, "outputs": [], "source": [ "fig_vrfy_hist = plt.figure(figsize=(10.5, 5), dpi=90)\n", "axe_hist_full = fig_vrfy_hist.add_subplot(1, 1, 1)\n", - "plot_hist(axe_hist_full, data[\"verify_time\"], \"verification time ({})\".format(verify_unit), log_scale, hist_size_sign_time);" + "plot_hist(axe_hist_full, data[\"verify_time\"], \"verification time ({})\".format(verify_disp_unit), log_scale, hist_size_sign_time);" ] }, { @@ -449,8 +429,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:05:33.971385Z", - "start_time": "2019-03-17T23:05:33.732857Z" + "end_time": "2019-03-18T18:16:05.236199Z", + "start_time": "2019-03-18T18:16:05.123540Z" } }, "outputs": [], @@ -466,7 +446,7 @@ " axe_sign_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_sign_avg.axhline(y=high_bound, alpha=0.7, linestyle=\"dotted\", color=\"orange\", label=\"Hight trim bound = {}\".format(high_bound))\n", - "axe_sign_avg.set_ylabel(\"signature time ({})\".format(sign_unit))\n", + "axe_sign_avg.set_ylabel(\"signature time ({})\".format(sign_disp_unit))\n", "axe_sign_avg.set_xlabel(\"index\")\n", "axe_sign_avg.legend(loc=\"best\")\n", "\n", @@ -474,7 +454,7 @@ "avg_vrfy_1000 = moving_average(data[\"verify_time\"], 1000)\n", "axe_vrfy_avg.plot(avg_vrfy_100, label=\"window = 100\")\n", "axe_vrfy_avg.plot(avg_vrfy_1000, label=\"window = 1000\")\n", - "axe_vrfy_avg.set_ylabel(\"verification time ({})\".format(verify_unit))\n", + "axe_vrfy_avg.set_ylabel(\"verification time ({})\".format(verify_disp_unit))\n", "axe_vrfy_avg.set_xlabel(\"index\")\n", "axe_vrfy_avg.legend(loc=\"best\")\n", "\n", @@ -485,7 +465,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Nonce MSB and LSB histograms" + "### Nonce MSB and LSB histograms\n", + "Expected to be uniform over [0, 255]." ] }, { @@ -493,8 +474,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:05:36.256032Z", - "start_time": "2019-03-17T23:05:35.302194Z" + "end_time": "2019-03-18T18:16:06.352067Z", + "start_time": "2019-03-18T18:16:06.059476Z" } }, "outputs": [], @@ -514,7 +495,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Nonce bit length histogram" + "### Nonce bit length vs signature time heatmap\n", + "Also contains nonce 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." ] }, { @@ -522,8 +504,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T23:05:45.320760Z", - "start_time": "2019-03-17T23:05:44.951189Z" + "end_time": "2019-03-18T18:16:07.625289Z", + "start_time": "2019-03-18T18:16:07.544334Z" } }, "outputs": [], @@ -537,7 +519,7 @@ "h, xe, ye = np.histogram2d(bl_data, data_trimmed[\"sign_time\"], bins=[max(bl_data) - min(bl_data), hist_size_sign_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(\"nonce bit length\")\n", - "axe_bl_heat.set_ylabel(\"signature time ({})\".format(sign_unit))\n", + "axe_bl_heat.set_ylabel(\"signature time ({})\".format(sign_disp_unit))\n", "\n", "plot_hist(axe_bl_hist, bl_data, \"nonce bit length\", log_scale, align=\"right\")\n", "fig_bl.colorbar(im, ax=[axe_bl_heat, axe_bl_hist])\n", @@ -546,6 +528,74 @@ ] }, { + "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:16:48.791656Z", + "start_time": "2019-03-18T18:16:45.435426Z" + } + }, + "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:16:55.343989Z", + "start_time": "2019-03-18T18:16:49.543154Z" + } + }, + "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": { + "ExecuteTime": { + "end_time": "2019-03-18T18:16:56.289305Z", + "start_time": "2019-03-18T18:16:56.278296Z" + } + }, + "outputs": [], + "source": [ + "max_priv = max(data[\"priv\"])\n", + "max_nonce = max(data[\"nonce\"])\n", + "display(max_priv < r)\n", + "display(r <= p or max_priv > p)\n", + "display(max_nonce < r)\n", + "display(r <= p or max_nonce > p)\n", + "display(max_priv.bit_length() == r.bit_length())\n", + "display(max_nonce.bit_length() == r.bit_length())" + ] + }, + { "cell_type": "code", "execution_count": null, "metadata": {}, @@ -555,8 +605,8 @@ ], "metadata": { "@webio": { - "lastCommId": "2218f80b2f784436bce6ffed5d971ea3", - "lastKernelId": "1c06331a-17dd-4743-9e31-832000e597c8" + "lastCommId": "7c4c5d836a8d43e5846df95890bbafa3", + "lastKernelId": "b01f6c07-c08b-4348-a503-dc2c9cf1db89" }, "hide_input": false, "kernelspec": { 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": { diff --git a/util/utils.py b/util/utils.py index d6b9aed..5359988 100644 --- a/util/utils.py +++ b/util/utils.py @@ -16,6 +16,21 @@ def moving_average(a, n) : return ret[n - 1:] / n +def time_scale(data, orig_unit, target_unit, scaling_factor): + units = { + "milli": ("ms", 1000000), + "micro": (r"$\mu s$", 1000), + "nano": ("ns", 1) + } + upper = units[orig_unit][1] + lower = units[target_unit][1] * scaling_factor + if upper > lower: + data *= upper // lower + elif lower > upper: + np.floor_divide(data, lower // upper, data) + return (r"$\frac{1}{" + str(scaling_factor) + "}$" if scaling_factor != 1 else "") + units[target_unit][0] + + def plot_hist(axes, data, xlabel=None, log=False, avg=True, median=True, bins=None, **kwargs): time_max = max(data) time_min = min(data) |
