diff options
| author | J08nY | 2019-03-21 18:10:50 +0100 |
|---|---|---|
| committer | J08nY | 2019-03-21 18:10:50 +0100 |
| commit | 74f08103b0b17c9139c18168e27f79efe6324eb6 (patch) | |
| tree | 353cc52c55b79a7e034115a2f7297faf9dccf24c /util | |
| parent | 8dda00c46e73f2a44e7c387a6b4e86055ffecea2 (diff) | |
| download | ECTester-74f08103b0b17c9139c18168e27f79efe6324eb6.tar.gz ECTester-74f08103b0b17c9139c18168e27f79efe6324eb6.tar.zst ECTester-74f08103b0b17c9139c18168e27f79efe6324eb6.zip | |
Diffstat (limited to 'util')
| -rw-r--r-- | util/plot_dh.ipynb | 176 | ||||
| -rw-r--r-- | util/plot_dsa.ipynb | 220 | ||||
| -rw-r--r-- | util/plot_gen.ipynb | 111 | ||||
| -rw-r--r-- | util/utils.py | 16 |
4 files changed, 368 insertions, 155 deletions
diff --git a/util/plot_dh.ipynb b/util/plot_dh.ipynb index 2e82292..e42b25c 100644 --- a/util/plot_dh.ipynb +++ b/util/plot_dh.ipynb @@ -9,11 +9,11 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:35:11.337869Z", - "start_time": "2019-03-18T18:35:11.331608Z" + "end_time": "2019-03-19T13:35:38.954375Z", + "start_time": "2019-03-19T13:35:38.578219Z" } }, "outputs": [], @@ -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, time_scale\n", + "from utils import plot_hist, moving_average, hw, time_scale, hist_size_func\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-18T18:35:28.957529Z", - "start_time": "2019-03-18T18:35:28.952399Z" + "end_time": "2019-03-19T12:43:15.121139Z", + "start_time": "2019-03-19T12:43:15.117537Z" } }, "outputs": [], @@ -87,7 +87,7 @@ "\n", "# What function to use to calculate number of histogram bins of time\n", "# one of \"sqrt\", \"sturges\", \"rice\", \"scott\" and \"fd\" or a number specifying the number of bins\n", - "hist_size = \"rice\"" + "hist_size = \"sturges\"" ] }, { @@ -102,8 +102,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:35:30.394517Z", - "start_time": "2019-03-18T18:35:29.499890Z" + "end_time": "2019-03-19T12:43:16.687260Z", + "start_time": "2019-03-19T12:43:16.031604Z" } }, "outputs": [], @@ -170,21 +170,8 @@ "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", - "elif hist_size == \"sturges\":\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: int(log(n, 2)) + 1\n", - "elif hist_size == \"rice\":\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: int(2 * n**(1/3))\n", - "elif hist_size == \"scott\":\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: (xmax - xmin) // int((3.5 * sqrt(var)) / (n**(1/3)))\n", - "elif hist_size == \"fd\":\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: (xmax - xmin) // int(2 * (xupper - xlower) / (n**(1/3)))\n", - "else:\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: hist_size\n", - "\n", - "hist_size_time = hist_size_func(description.nobs, min_time, max_time, description.variance, quantiles[1], quantiles[3])\n", - "hist_size_time_trim = hist_size_func(description_trim.nobs, description_trim.minmax[0], description_trim.minmax[1], description_trim.variance, quantiles_trim[1], quantiles_trim[3])\n", + "hist_size_time = hist_size_func(hist_size)(description.nobs, min_time, max_time, description.variance, quantiles[1], quantiles[3])\n", + "hist_size_time_trim = hist_size_func(hist_size)(description_trim.nobs, description_trim.minmax[0], description_trim.minmax[1], description_trim.variance, quantiles_trim[1], quantiles_trim[3])\n", "\n", "if hist_size_time < 30:\n", " hist_size_time = max_time - min_time\n", @@ -211,8 +198,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:35:31.158217Z", - "start_time": "2019-03-18T18:35:31.144280Z" + "end_time": "2019-03-19T12:43:17.706648Z", + "start_time": "2019-03-19T12:43:17.695215Z" } }, "outputs": [], @@ -239,8 +226,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:35:32.593550Z", - "start_time": "2019-03-18T18:35:32.588147Z" + "end_time": "2019-03-19T12:43:19.507884Z", + "start_time": "2019-03-19T12:43:19.502941Z" } }, "outputs": [], @@ -262,8 +249,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:35:33.252850Z", - "start_time": "2019-03-18T18:35:33.245928Z" + "end_time": "2019-03-19T12:43:20.963153Z", + "start_time": "2019-03-19T12:43:20.956502Z" } }, "outputs": [], @@ -293,14 +280,14 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:35:34.581846Z", - "start_time": "2019-03-18T18:35:34.472065Z" + "end_time": "2019-03-19T12:43:22.063050Z", + "start_time": "2019-03-19T12:43:21.967845Z" } }, "outputs": [], "source": [ "fig_private = plt.figure(figsize=(10.5, 8), dpi=90)\n", - "axe_private = fig_private.add_subplot(1, 1, 1)\n", + "axe_private = fig_private.add_subplot(1, 1, 1, title=\"Private key MSB vs key agreement time\")\n", "priv_msb = np.array(list(map(lambda x: x >> (bit_size - 8), data_trimmed[\"priv\"])), dtype=np.dtype(\"u1\"))\n", "max_msb = max(priv_msb)\n", "min_msb = min(priv_msb)\n", @@ -313,6 +300,7 @@ "axe_private.set_ylabel(\"key agreement time ({})\".format(time_disp_unit))\n", "fig_private.colorbar(im, ax=axe_private)\n", "\n", + "fig_private.tight_layout()\n", "del priv_msb" ] }, @@ -331,16 +319,16 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:35:39.673526Z", - "start_time": "2019-03-18T18:35:38.253945Z" + "end_time": "2019-03-19T12:47:12.436692Z", + "start_time": "2019-03-19T12:47:11.310271Z" } }, "outputs": [], "source": [ "fig_priv_hist = plt.figure(figsize=(10.5, 12), dpi=90)\n", "gs = gridspec.GridSpec(2, 1, height_ratios=[2.5, 1])\n", - "axe_priv_hist = fig_priv_hist.add_subplot(gs[0])\n", - "axe_priv_hist_hw = fig_priv_hist.add_subplot(gs[1], sharex = axe_priv_hist)\n", + "axe_priv_hist = fig_priv_hist.add_subplot(gs[0], title=\"Private key Hamming weight vs key agreement time\")\n", + "axe_priv_hist_hw = fig_priv_hist.add_subplot(gs[1], sharex=axe_priv_hist, title=\"Private key Hamming weight\")\n", "priv_hw = np.array(list(map(hw, data_trimmed[\"priv\"])), dtype=np.dtype(\"u2\"))\n", "h, xe, ye = np.histogram2d(priv_hw, data_trimmed[\"time\"], bins=[max(priv_hw) - min(priv_hw), hist_size_time_trim])\n", "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", @@ -356,6 +344,8 @@ "norm_pdf = norm_dist.pdf(pdf_range, *param[:-2], loc=param[-2], scale=param[-1]) * description_trim.nobs\n", "axe_priv_hist_hw.plot(pdf_range, norm_pdf, label=\"fitted normal distribution\")\n", "axe_priv_hist_hw.legend(loc=\"best\")\n", + "\n", + "fig_priv_hist.tight_layout()\n", "fig_priv_hist.colorbar(im, ax=[axe_priv_hist, axe_priv_hist_hw])\n", "\n", "display(HTML(\"<b>Private key Hamming weight fitted with normal distribution:</b>\"))\n", @@ -376,8 +366,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:35:51.604298Z", - "start_time": "2019-03-18T18:35:40.980632Z" + "end_time": "2019-03-19T12:47:20.496134Z", + "start_time": "2019-03-19T12:47:20.360405Z" } }, "outputs": [], @@ -386,7 +376,9 @@ "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_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);" + "plot_hist(axe_hist_trim, data_trimmed[\"time\"], \"key agreement time ({})\".format(time_disp_unit), log_scale, hist_size_time_trim);\n", + "\n", + "fig_ka_hist.tight_layout()" ] }, { @@ -401,14 +393,14 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:36:00.467782Z", - "start_time": "2019-03-18T18:36:00.418942Z" + "end_time": "2019-03-19T12:47:21.706585Z", + "start_time": "2019-03-19T12:47:21.658363Z" } }, "outputs": [], "source": [ "fig_avg = plt.figure(figsize=(10.5, 7), dpi=90)\n", - "axe_avg = fig_avg.add_subplot(1, 1, 1)\n", + "axe_avg = fig_avg.add_subplot(1, 1, 1, title=\"Moving average of key agreement time\")\n", "avg_100 = moving_average(data[\"time\"], 100)\n", "avg_1000 = moving_average(data[\"time\"], 1000)\n", "axe_avg.plot(avg_100, label=\"window = 100\")\n", @@ -421,6 +413,7 @@ "axe_avg.set_xlabel(\"index\")\n", "axe_avg.legend(loc=\"best\")\n", "\n", + "fig_avg.tight_layout()\n", "del avg_100, avg_1000" ] }, @@ -437,8 +430,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:36:02.558769Z", - "start_time": "2019-03-18T18:36:02.216115Z" + "end_time": "2019-03-19T12:47:32.875112Z", + "start_time": "2019-03-19T12:47:32.542216Z" }, "hide_input": false }, @@ -447,11 +440,12 @@ "fig_priv_hists = plt.figure(figsize=(10.5, 8), dpi=90)\n", "priv_msb = np.array(list(map(lambda x: x >> (bit_size - 8), data[\"priv\"])), dtype=np.dtype(\"u1\"))\n", "priv_lsb = np.array(list(map(lambda x: x & 0xff, data[\"priv\"])), dtype=np.dtype(\"u1\"))\n", - "axe_msb_s_hist = fig_priv_hists.add_subplot(2, 1, 1)\n", - "axe_lsb_s_hist = fig_priv_hists.add_subplot(2, 1, 2)\n", + "axe_msb_s_hist = fig_priv_hists.add_subplot(2, 1, 1, title=\"Private key MSB\")\n", + "axe_lsb_s_hist = fig_priv_hists.add_subplot(2, 1, 2, title=\"Private key LSB\")\n", "msb_h = plot_hist(axe_msb_s_hist, priv_msb, \"private key MSB\", log_scale, False, False)\n", "lsb_h = plot_hist(axe_lsb_s_hist, priv_lsb, \"private key LSB\", log_scale, False, False)\n", "\n", + "fig_priv_hists.tight_layout()\n", "del priv_msb, priv_lsb" ] }, @@ -468,16 +462,16 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:36:04.445752Z", - "start_time": "2019-03-18T18:36:04.317542Z" + "end_time": "2019-03-19T12:47:34.638019Z", + "start_time": "2019-03-19T12:47:34.479903Z" } }, "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", + "axe_bl_heat = fig_bl.add_subplot(gs[0], title=\"Private key bit length vs keygen time\")\n", + "axe_bl_hist = fig_bl.add_subplot(gs[1], sharex=axe_bl_heat, title=\"Private key bit length\")\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", @@ -486,6 +480,8 @@ "axe_bl_heat.set_ylabel(\"key agreement time ({})\".format(time_disp_unit))\n", "\n", "plot_hist(axe_bl_hist, bl_data, \"Private key bit length\", log_scale, align=\"right\")\n", + "\n", + "fig_bl.tight_layout()\n", "fig_bl.colorbar(im, ax=[axe_bl_heat, axe_bl_hist])\n", "\n", "del bl_data" @@ -495,6 +491,48 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "### Private key bit length histogram given time\n", + "Interactively shows the histogram of private key bit length given a selected time range centered around `center` of width `width`. Ideally, the means of these conditional distributions are equal, while the variances can vary." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig_bl_time = plt.figure(figsize=(10.5, 5), dpi=90)\n", + "axe_bl_time = fig_bl_time.add_subplot(111)\n", + "axe_bl_time.set_autoscalex_on(False)\n", + "def f(center, width):\n", + " lower_bnd = center - width/2\n", + " upper_bnd = center + width/2\n", + " values = data_trimmed[np.logical_and(data_trimmed[\"time\"] <= upper_bnd,\n", + " data_trimmed[\"time\"] >= lower_bnd)]\n", + " axe_bl_time.clear()\n", + " axe_bl_time.set_title(\"Private key bit length, given key agreement time $\\in ({}, {})$ {}\".format(int(lower_bnd), int(upper_bnd), sign_disp_unit))\n", + " bl_data = np.array(list(map(lambda x: x.bit_length(), values[\"priv\"])), dtype=np.dtype(\"u2\"))\n", + " plot_hist(axe_bl_time, bl_data, \"private key bit length\", bins=11, range=(bit_size-10, bit_size+1), align=\"left\")\n", + " axe_bl_time.set_xlim((bit_size-10, bit_size))\n", + " fig_bl_time.tight_layout()\n", + "\n", + "center_w = widgets.IntSlider(min=min(data_trimmed[\"time\"]),\n", + " max=max(data_trimmed[\"time\"]),\n", + " step=1,\n", + " value=description_sign_trim.mean,\n", + " continuous_update=False,\n", + " description=\"center {}\".format(sign_disp_unit))\n", + "width_w = widgets.IntSlider(min=1, max=100, continuous_update=False,\n", + " description=\"width {}\".format(sign_disp_unit))\n", + "w = interactive(f, center=center_w,\n", + " width=width_w)\n", + "display(w)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "## Validation\n", "Perform some tests on the produced data and compare to expected results.\n", "\n", @@ -530,7 +568,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "All of the following tests should pass (e.g. be true):" + "All of the following tests should pass (e.g. be true), given a large enough sample and run without the `--fixed` or `-priv/-npriv` flags:" ] }, { @@ -540,16 +578,40 @@ "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())" + "un = len(np.unique(data[\"priv\"])) != 1\n", + "if un:\n", + " print(\"Private keys are smaller than order:\\t\\t\\t\" + str(max_priv < r))\n", + " print(\"Private keys are larger than prime(if order > prime):\\t\" + str(r <= p or max_priv > p))\n", + " print(\"Private keys reach full bit length of order:\\t\\t\" + str(max_priv.bit_length() == r.bit_length()))" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2019-03-19T12:53:48.777395Z", + "start_time": "2019-03-19T12:53:48.766190Z" + } + }, + "outputs": [], + "source": [ + "if un:\n", + " print(\"Private key bit length (min, max):\" + str(min(data[\"priv\"]).bit_length()) + \", \" + str(max(data[\"priv\"]).bit_length()))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "@webio": { - "lastCommId": "73e8d2ab400746298b234c8983722e8e", - "lastKernelId": "cedfe41c-66b9-4611-ad6f-ab448422bbd2" + "lastCommId": "18de549d83f84e128074fc96e268d86f", + "lastKernelId": "875ada23-b504-4c96-8f24-68b5d72faab5" }, "hide_input": false, "kernelspec": { diff --git a/util/plot_dsa.ipynb b/util/plot_dsa.ipynb index 503bde8..6fa5663 100644 --- a/util/plot_dsa.ipynb +++ b/util/plot_dsa.ipynb @@ -12,8 +12,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:08:10.526799Z", - "start_time": "2019-03-18T18:08:10.073972Z" + "end_time": "2019-03-21T16:47:51.573214Z", + "start_time": "2019-03-21T16:47:50.777035Z" } }, "outputs": [], @@ -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, time_scale\n", + "from utils import plot_hist, moving_average, hw, time_scale, hist_size_func\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-18T18:15:54.067732Z", - "start_time": "2019-03-18T18:15:54.063679Z" + "end_time": "2019-03-21T16:47:51.578911Z", + "start_time": "2019-03-21T16:47:51.575142Z" } }, "outputs": [], @@ -67,7 +67,7 @@ "scaling_factor = 1\n", "\n", "# The amount of entries skipped from the beginning of the file, as they are usually outliers.\n", - "skip_first = 100\n", + "skip_first = 10\n", "\n", "# Whether to plot things in logarithmic scale or not.\n", "log_scale = False\n", @@ -103,8 +103,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:15:55.985799Z", - "start_time": "2019-03-18T18:15:55.495414Z" + "end_time": "2019-03-21T16:47:55.190977Z", + "start_time": "2019-03-21T16:47:52.428880Z" } }, "outputs": [], @@ -177,21 +177,8 @@ "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", - "elif hist_size == \"sturges\":\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: int(log(n, 2)) + 1\n", - "elif hist_size == \"rice\":\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: int(2 * n**(1/3))\n", - "elif hist_size == \"scott\":\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: (xmax - xmin) // int((3.5 * sqrt(var)) / (n**(1/3)))\n", - "elif hist_size == \"fd\":\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: (xmax - xmin) // int(2 * (xupper - xlower) / (n**(1/3)))\n", - "else:\n", - " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: hist_size\n", - "\n", - "hist_size_sign_time = hist_size_func(description_sign.nobs, min_sign_time, max_sign_time, description_sign.variance, quantiles_sign[1], quantiles_sign[3])\n", - "hist_size_sign_time_trim = hist_size_func(description_sign_trim.nobs, description_sign_trim.minmax[0], description_sign_trim.minmax[1], description_sign_trim.variance, quantiles_sign_trim[1], quantiles_sign_trim[3])\n", + "hist_size_sign_time = hist_size_func(hist_size)(description_sign.nobs, min_sign_time, max_sign_time, description_sign.variance, quantiles_sign[1], quantiles_sign[3])\n", + "hist_size_sign_time_trim = hist_size_func(hist_size)(description_sign_trim.nobs, description_sign_trim.minmax[0], description_sign_trim.minmax[1], description_sign_trim.variance, quantiles_sign_trim[1], quantiles_sign_trim[3])\n", "\n", "if hist_size_sign_time < 30:\n", " hist_size_sign_time = max_sign_time - min_sign_time\n", @@ -218,8 +205,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:15:57.175564Z", - "start_time": "2019-03-18T18:15:57.161611Z" + "end_time": "2019-03-21T16:18:19.188665Z", + "start_time": "2019-03-21T16:18:19.164737Z" } }, "outputs": [], @@ -246,8 +233,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:15:58.257820Z", - "start_time": "2019-03-18T18:15:58.254036Z" + "end_time": "2019-03-21T16:18:20.110503Z", + "start_time": "2019-03-21T16:18:20.099333Z" } }, "outputs": [], @@ -269,13 +256,15 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:15:58.917927Z", - "start_time": "2019-03-18T18:15:58.909693Z" + "end_time": "2019-03-21T16:18:20.768858Z", + "start_time": "2019-03-21T16:18:20.758881Z" } }, "outputs": [], "source": [ - "display(\"Bitsize:\", bit_size)" + "display(\"Bitsize:\", bit_size)\n", + "display(\"Histogram time bins: {}\".format(hist_size_sign_time))\n", + "display(\"Histogram time bins(trimmed): {}\".format(hist_size_sign_time_trim))" ] }, { @@ -298,14 +287,14 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:15:59.977656Z", - "start_time": "2019-03-18T18:15:59.926337Z" + "end_time": "2019-03-21T16:18:22.549846Z", + "start_time": "2019-03-21T16:18:22.332677Z" } }, "outputs": [], "source": [ "fig_nonce = plt.figure(figsize=(10.5, 8), dpi=90)\n", - "axe_nonce = fig_nonce.add_subplot(1, 1, 1)\n", + "axe_nonce = fig_nonce.add_subplot(1, 1, 1, title=\"Nonce MSB vs signature time\")\n", "nonce_msb = np.array(list(map(lambda x: x >> (bit_size - 8), data_trimmed[\"nonce\"])), dtype=np.dtype(\"u1\"))\n", "max_msb = max(nonce_msb)\n", "min_msb = min(nonce_msb)\n", @@ -314,10 +303,11 @@ "extent = [min_msb, max_msb, yedges[0], yedges[-1]]\n", "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_xlabel(\"nonce MSB value\")\n", "axe_nonce.set_ylabel(\"signature time ({})\".format(sign_disp_unit))\n", "fig_nonce.colorbar(im, ax=axe_nonce)\n", "\n", + "fig_nonce.tight_layout()\n", "del nonce_msb" ] }, @@ -336,16 +326,16 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:01.977710Z", - "start_time": "2019-03-18T18:16:01.717704Z" + "end_time": "2019-03-21T16:18:26.230002Z", + "start_time": "2019-03-21T16:18:24.323208Z" } }, "outputs": [], "source": [ "fig_nonce_hist = plt.figure(figsize=(10.5, 12), dpi=90)\n", "gs = gridspec.GridSpec(2, 1, height_ratios=[2.5, 1])\n", - "axe_nonce_hist = fig_nonce_hist.add_subplot(gs[0])\n", - "axe_nonce_hist_hw = fig_nonce_hist.add_subplot(gs[1], sharex = axe_nonce_hist)\n", + "axe_nonce_hist = fig_nonce_hist.add_subplot(gs[0], title=\"Nonce Hamming weight vs signature time\")\n", + "axe_nonce_hist_hw = fig_nonce_hist.add_subplot(gs[1], sharex=axe_nonce_hist, title=\"Nonce Hamming weight\")\n", "nonce_hw = np.array(list(map(hw, data_trimmed[\"nonce\"])), dtype=np.dtype(\"u2\"))\n", "h, xe, ye = np.histogram2d(nonce_hw, data_trimmed[\"sign_time\"], bins=[max(nonce_hw) - min(nonce_hw), hist_size_sign_time_trim])\n", "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", @@ -361,11 +351,13 @@ "norm_pdf = norm_dist.pdf(pdf_range, *param[:-2], loc=param[-2], scale=param[-1]) * description_sign_trim.nobs\n", "axe_nonce_hist_hw.plot(pdf_range, norm_pdf, label=\"fitted normal distribution\")\n", "axe_nonce_hist_hw.legend(loc=\"best\")\n", - "fig_nonce_hist.colorbar(im, ax=[axe_nonce_hist, axe_nonce_hist_hw])\n", + "\n", "\n", "display(HTML(\"<b>Nonce Hamming weight fitted with normal distribution:</b>\"))\n", "display(HTML(tabulate.tabulate([(\"Mean\", \"Variance\"), param], tablefmt=\"html\")))\n", "\n", + "fig_nonce_hist.tight_layout()\n", + "fig_nonce_hist.colorbar(im, ax=[axe_nonce_hist, axe_nonce_hist_hw])\n", "del nonce_hw" ] }, @@ -381,17 +373,18 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:03.232728Z", - "start_time": "2019-03-18T18:16:03.134237Z" + "end_time": "2019-03-21T16:18:48.188494Z", + "start_time": "2019-03-21T16:18:39.850301Z" } }, "outputs": [], "source": [ "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", + "axe_hist_full = fig_sig_hist.add_subplot(2, 1, 1, title=\"Signature time\")\n", + "axe_hist_trim = fig_sig_hist.add_subplot(2, 1, 2, title=\"Signature time (trimmed)\")\n", "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);" + "plot_hist(axe_hist_trim, data_trimmed[\"sign_time\"], \"signature time ({})\".format(sign_disp_unit), log_scale, hist_size_sign_time_trim);\n", + "fig_sig_hist.tight_layout()" ] }, { @@ -406,15 +399,16 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:04.380116Z", - "start_time": "2019-03-18T18:16:04.227481Z" + "end_time": "2019-03-21T16:19:05.618320Z", + "start_time": "2019-03-21T16:18:53.161932Z" } }, "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_disp_unit), log_scale, hist_size_sign_time);" + "axe_hist_full = fig_vrfy_hist.add_subplot(1, 1, 1, title=\"Verification time\")\n", + "plot_hist(axe_hist_full, data[\"verify_time\"], \"verification time ({})\".format(verify_disp_unit), log_scale, hist_size_sign_time);\n", + "fig_vrfy_hist.tight_layout()" ] }, { @@ -429,15 +423,15 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:05.236199Z", - "start_time": "2019-03-18T18:16:05.123540Z" + "end_time": "2019-03-21T16:19:56.783127Z", + "start_time": "2019-03-21T16:19:56.375647Z" } }, "outputs": [], "source": [ "fig_avg = plt.figure(figsize=(10.5, 8), dpi=90)\n", - "axe_sign_avg = fig_avg.add_subplot(2, 1, 1)\n", - "axe_vrfy_avg = fig_avg.add_subplot(2, 1, 2, sharex=axe_sign_avg)\n", + "axe_sign_avg = fig_avg.add_subplot(2, 1, 1, title=\"Moving average of signature time\")\n", + "axe_vrfy_avg = fig_avg.add_subplot(2, 1, 2, sharex=axe_sign_avg, title=\"Moving average of verification time\")\n", "avg_sign_100 = moving_average(data[\"sign_time\"], 100)\n", "avg_sign_1000 = moving_average(data[\"sign_time\"], 1000)\n", "axe_sign_avg.plot(avg_sign_100, label=\"window = 100\")\n", @@ -458,6 +452,8 @@ "axe_vrfy_avg.set_xlabel(\"index\")\n", "axe_vrfy_avg.legend(loc=\"best\")\n", "\n", + "fig_avg.tight_layout()\n", + "\n", "del avg_sign_100, avg_sign_1000, avg_vrfy_100, avg_vrfy_1000" ] }, @@ -474,8 +470,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:06.352067Z", - "start_time": "2019-03-18T18:16:06.059476Z" + "end_time": "2019-03-21T16:20:00.354254Z", + "start_time": "2019-03-21T16:19:59.289152Z" } }, "outputs": [], @@ -483,11 +479,12 @@ "fig_nonce_hists = plt.figure(figsize=(10.5, 8), dpi=90)\n", "nonce_msb = np.array(list(map(lambda x: x >> (bit_size - 8), data[\"nonce\"])), dtype=np.dtype(\"u1\"))\n", "nonce_lsb = np.array(list(map(lambda x: x & 0xff, data[\"nonce\"])), dtype=np.dtype(\"u1\"))\n", - "axe_msb_n_hist = fig_nonce_hists.add_subplot(2, 1, 1)\n", - "axe_lsb_n_hist = fig_nonce_hists.add_subplot(2, 1, 2)\n", + "axe_msb_n_hist = fig_nonce_hists.add_subplot(2, 1, 1, title=\"Nonce MSB\")\n", + "axe_lsb_n_hist = fig_nonce_hists.add_subplot(2, 1, 2, title=\"Nonce LSB\")\n", "plot_hist(axe_msb_n_hist, nonce_msb, \"nonce MSB\", log_scale, False, False)\n", "plot_hist(axe_lsb_n_hist, nonce_lsb, \"nonce LSB\", log_scale, False, False)\n", "\n", + "fig_nonce_hists.tight_layout()\n", "del nonce_msb, nonce_lsb" ] }, @@ -504,16 +501,16 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:07.625289Z", - "start_time": "2019-03-18T18:16:07.544334Z" + "end_time": "2019-03-21T16:20:02.737798Z", + "start_time": "2019-03-21T16:20:02.481429Z" } }, "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", + "axe_bl_heat = fig_bl.add_subplot(gs[0], title=\"Nonce bit length vs signature time\")\n", + "axe_bl_hist = fig_bl.add_subplot(gs[1], sharex=axe_bl_heat, title=\"Nonce bit length\")\n", "bl_data = np.array(list(map(lambda x: x.bit_length(), data_trimmed[\"nonce\"])), dtype=np.dtype(\"u2\"))\n", "\n", "h, xe, ye = np.histogram2d(bl_data, data_trimmed[\"sign_time\"], bins=[max(bl_data) - min(bl_data), hist_size_sign_time_trim])\n", @@ -522,6 +519,8 @@ "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", + "\n", + "fig_bl.tight_layout()\n", "fig_bl.colorbar(im, ax=[axe_bl_heat, axe_bl_hist])\n", "\n", "del bl_data" @@ -531,9 +530,58 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "### Nonce bit length histogram given time\n", + "Interactively shows the histogram of nonce bit length given a selected time range centered around `center` of width `width`. Ideally, the means of these conditional distributions are equal, while the variances can vary." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2019-03-21T16:20:10.306709Z", + "start_time": "2019-03-21T16:20:10.102626Z" + }, + "scrolled": false + }, + "outputs": [], + "source": [ + "fig_bl_time = plt.figure(figsize=(10.5, 5), dpi=90)\n", + "axe_bl_time = fig_bl_time.add_subplot(111)\n", + "axe_bl_time.set_autoscalex_on(False)\n", + "def f(center, width):\n", + " lower_bnd = center - width/2\n", + " upper_bnd = center + width/2\n", + " values = data_trimmed[np.logical_and(data_trimmed[\"sign_time\"] <= upper_bnd,\n", + " data_trimmed[\"sign_time\"] >= lower_bnd)]\n", + " axe_bl_time.clear()\n", + " axe_bl_time.set_title(\"Nonce bit length, given signature time $\\in ({}, {})$ {}\".format(int(lower_bnd), int(upper_bnd), sign_disp_unit))\n", + " bl_data = np.array(list(map(lambda x: x.bit_length(), values[\"nonce\"])), dtype=np.dtype(\"u2\"))\n", + " plot_hist(axe_bl_time, bl_data, \"nonce bit length\", bins=11, range=(bit_size-10, bit_size+1), align=\"left\")\n", + " axe_bl_time.set_xlim((bit_size-10, bit_size))\n", + " fig_bl_time.tight_layout()\n", + "\n", + "center_w = widgets.IntSlider(min=min(data_trimmed[\"sign_time\"]),\n", + " max=max(data_trimmed[\"sign_time\"]),\n", + " step=1,\n", + " value=description_sign_trim.mean,\n", + " continuous_update=False,\n", + " description=\"center {}\".format(sign_disp_unit))\n", + "width_w = widgets.IntSlider(min=1, max=100, continuous_update=False,\n", + " description=\"width {}\".format(sign_disp_unit))\n", + "w = interactive(f, center=center_w,\n", + " width=width_w)\n", + "display(w)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "## Validation\n", "Perform some tests on the produced data and compare to expected results.\n", "\n", + "\n", "This requires some information about the used curve, enter it below." ] }, @@ -542,8 +590,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:48.791656Z", - "start_time": "2019-03-18T18:16:45.435426Z" + "end_time": "2019-03-21T15:24:57.397880Z", + "start_time": "2019-03-21T15:24:37.395614Z" } }, "outputs": [], @@ -557,8 +605,8 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:55.343989Z", - "start_time": "2019-03-18T18:16:49.543154Z" + "end_time": "2019-03-21T15:25:05.137250Z", + "start_time": "2019-03-21T15:24:59.218945Z" } }, "outputs": [], @@ -571,7 +619,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "All of the following tests should pass (e.g. be true):" + "All of the following tests should pass (e.g. be true), given a large enough sample and run without the `--fixed` or `-priv/-npriv` flags:" ] }, { @@ -579,20 +627,40 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-18T18:16:56.289305Z", - "start_time": "2019-03-18T18:16:56.278296Z" - } + "end_time": "2019-03-21T16:23:08.618543Z", + "start_time": "2019-03-21T16:23:08.451827Z" + }, + "scrolled": true }, "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())" + "un = len(np.unique(data[\"priv\"])) != 1\n", + "if un:\n", + " print(\"Private keys are smaller than order:\\t\\t\\t\" + str(max_priv < r))\n", + " print(\"Private keys are larger than prime(if order > prime):\\t\" + str(r <= p or max_priv > p))\n", + "print(\"Nonces are smaller than order:\\t\\t\\t\\t\" + str(max_nonce < r))\n", + "print(\"Nonces are larger than prime(if order > prime):\\t\\t\" + str(r <= p or max_nonce > p))\n", + "if un:\n", + " print(\"Private keys reach full bit length of order:\\t\\t\" + str(max_priv.bit_length() == r.bit_length()))\n", + "print(\"Nonces reach full bit length of order:\\t\\t\\t\" + str(max_nonce.bit_length() == r.bit_length()))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2019-03-21T16:23:09.355514Z", + "start_time": "2019-03-21T16:23:09.315702Z" + } + }, + "outputs": [], + "source": [ + "if un:\n", + " print(\"Private key bit length (min, max):\" + str(min(data[\"priv\"]).bit_length()) + \", \" + str(max(data[\"priv\"]).bit_length()))\n", + "print(\"Nonce bit length (min, max):\" + str(min(data[\"nonce\"]).bit_length()) + \", \" + str(max(data[\"nonce\"]).bit_length()))" ] }, { @@ -605,8 +673,8 @@ ], "metadata": { "@webio": { - "lastCommId": "7c4c5d836a8d43e5846df95890bbafa3", - "lastKernelId": "b01f6c07-c08b-4348-a503-dc2c9cf1db89" + "lastCommId": "9597ec08f0744c0c9aff275fad95d237", + "lastKernelId": "e6055c6c-6313-439b-909b-d90592f67d26" }, "hide_input": false, "kernelspec": { diff --git a/util/plot_gen.ipynb b/util/plot_gen.ipynb index db618cc..1b8e94d 100644 --- a/util/plot_gen.ipynb +++ b/util/plot_gen.ipynb @@ -272,13 +272,15 @@ "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2019-03-17T19:16:44.688872Z", - "start_time": "2019-03-17T19:16:44.684485Z" + "end_time": "2019-03-19T13:41:01.468943Z", + "start_time": "2019-03-19T13:41:01.417360Z" } }, "outputs": [], "source": [ - "display(\"Bitsize:\", bit_size)" + "display(\"Bitsize:\", bit_size)\n", + "display(\"Histogram time bins: {}\".format(hist_size_gen_time))\n", + "display(\"Histogram time bins(trimmed): {}\".format(hist_size_gen_time_trim))" ] }, { @@ -308,7 +310,7 @@ "outputs": [], "source": [ "fig_private = plt.figure(figsize=(10.5, 8), dpi=90)\n", - "axe_private = fig_private.add_subplot(1, 1, 1)\n", + "axe_private = fig_private.add_subplot(1, 1, 1, title=\"Private key MSB vs keygen time\")\n", "priv_msb = np.array(list(map(lambda x: x >> (bit_size - 8), data_trimmed[\"priv\"])), dtype=np.dtype(\"u1\"))\n", "max_msb = max(priv_msb)\n", "min_msb = min(priv_msb)\n", @@ -321,6 +323,7 @@ "axe_private.set_ylabel(\"keygen time ({})\".format(gen_disp_unit))\n", "fig_private.colorbar(im, ax=axe_private)\n", "\n", + "fig_private.tight_layout()\n", "del priv_msb" ] }, @@ -347,8 +350,8 @@ "source": [ "fig_priv_hist = plt.figure(figsize=(10.5, 12), dpi=90)\n", "gs = gridspec.GridSpec(2, 1, height_ratios=[2.5, 1])\n", - "axe_priv_hist = fig_priv_hist.add_subplot(gs[0])\n", - "axe_priv_hist_hw = fig_priv_hist.add_subplot(gs[1], sharex = axe_priv_hist)\n", + "axe_priv_hist = fig_priv_hist.add_subplot(gs[0], title=\"Private key Hamming weight vs keygen time\")\n", + "axe_priv_hist_hw = fig_priv_hist.add_subplot(gs[1], sharex=axe_priv_hist, title=\"Private key Hamming weight\")\n", "priv_hw = np.array(list(map(hw, data_trimmed[\"priv\"])), dtype=np.dtype(\"u2\"))\n", "h, xe, ye = np.histogram2d(priv_hw, data_trimmed[\"gen_time\"], bins=[max(priv_hw) - min(priv_hw), hist_size_gen_time_trim])\n", "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", @@ -364,11 +367,13 @@ "norm_pdf = norm_dist.pdf(pdf_range, *param[:-2], loc=param[-2], scale=param[-1]) * description_gen_trim.nobs\n", "axe_priv_hist_hw.plot(pdf_range, norm_pdf, label=\"fitted normal distribution\")\n", "axe_priv_hist_hw.legend(loc=\"best\")\n", - "fig_priv_hist.colorbar(im, ax=[axe_priv_hist, axe_priv_hist_hw])\n", + "\n", "\n", "display(HTML(\"<b>Private key Hamming weight fitted with normal distribution:</b>\"))\n", "display(HTML(tabulate.tabulate([(\"Mean\", \"Variance\"), param], tablefmt=\"html\")))\n", "\n", + "fig_priv_hist.tight_layout()\n", + "fig_priv_hist.colorbar(im, ax=[axe_priv_hist, axe_priv_hist_hw])\n", "del priv_hw" ] }, @@ -394,7 +399,8 @@ "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_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);" + "plot_hist(axe_hist_trim, data_trimmed[\"gen_time\"], \"keygen time ({})\".format(gen_disp_unit), log_scale, hist_size_gen_time_trim);\n", + "fig_kg_hist.tight_layout()" ] }, { @@ -421,7 +427,8 @@ " 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_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);" + " plot_hist(axe_hist_trim, data_trimmed[\"export_time\"], \"export time ({})\".format(export_disp_unit), log_scale, hist_size_gen_time_trim);\n", + " fig_exp_hist.tight_layout()" ] }, { @@ -443,7 +450,7 @@ "outputs": [], "source": [ "fig_avg = plt.figure(figsize=(10.5, 7), dpi=90)\n", - "axe_avg = fig_avg.add_subplot(1, 1, 1)\n", + "axe_avg = fig_avg.add_subplot(1, 1, 1, title=\"Moving average of key generation time\")\n", "avg_100 = moving_average(data[\"gen_time\"], 100)\n", "avg_1000 = moving_average(data[\"gen_time\"], 1000)\n", "axe_avg.plot(avg_100, label=\"window = 100\")\n", @@ -455,6 +462,8 @@ "axe_avg.set_ylabel(\"keygen time ({})\".format(gen_disp_unit))\n", "axe_avg.set_xlabel(\"index\")\n", "axe_avg.legend(loc=\"best\")\n", + "\n", + "fig_avg.tight_layout()\n", "del avg_100, avg_1000" ] }, @@ -480,10 +489,12 @@ "fig_priv_hists = plt.figure(figsize=(10.5, 8), dpi=90)\n", "priv_msb = np.array(list(map(lambda x: x >> (bit_size - 8), data[\"priv\"])), dtype=np.dtype(\"u1\"))\n", "priv_lsb = np.array(list(map(lambda x: x & 0xff, data[\"priv\"])), dtype=np.dtype(\"u1\"))\n", - "axe_msb_s_hist = fig_priv_hists.add_subplot(2, 1, 1)\n", - "axe_lsb_s_hist = fig_priv_hists.add_subplot(2, 1, 2)\n", + "axe_msb_s_hist = fig_priv_hists.add_subplot(2, 1, 1, title=\"Private key MSB\")\n", + "axe_lsb_s_hist = fig_priv_hists.add_subplot(2, 1, 2, title=\"Private key LSB\")\n", "plot_hist(axe_msb_s_hist, priv_msb, \"private key MSB\", log_scale)\n", "plot_hist(axe_lsb_s_hist, priv_lsb, \"private key LSB\", log_scale)\n", + "\n", + "fig_priv_hists.tight_layout()\n", "del priv_msb, priv_lsb" ] }, @@ -517,8 +528,8 @@ "fig_pub_hists = plt.figure(figsize=(10.5, 14), dpi=90)\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", + " axe_msb_pub_hist = fig_pub_hists.add_subplot(4, 1, offset, title=\"{} coordinate MSB\".format(name))\n", + " axe_lsb_pub_hist = fig_pub_hists.add_subplot(4, 1, offset + 1, title=\"{} coordinate LSB\".format(name))\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", @@ -528,6 +539,8 @@ "_plot_coord(xs, \"X\", 1)\n", "_plot_coord(ys, \"Y\", 3)\n", "\n", + "fig_pub_hists.tight_layout()\n", + "\n", "del pub_coords, xs, ys" ] }, @@ -552,8 +565,8 @@ "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", + "axe_bl_heat = fig_bl.add_subplot(gs[0], title=\"Private key bit length vs keygen time\")\n", + "axe_bl_hist = fig_bl.add_subplot(gs[1], sharex=axe_bl_heat, title=\"Private key bit length\")\n", "\n", "bl_data = np.array(list(map(lambda x: x.bit_length(), data_trimmed[\"priv\"])), dtype=np.dtype(\"u2\"))\n", "\n", @@ -563,6 +576,8 @@ "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", + "\n", + "fig_priv_hist.tight_layout()\n", "fig_priv_hist.colorbar(im, ax=[axe_bl_heat, axe_bl_hist])\n", "\n", "del bl_data" @@ -572,6 +587,48 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "### Private key bit length histogram given time\n", + "Interactively shows the histogram of private key bit length given a selected time range centered around `center` of width `width`. Ideally, the means of these conditional distributions are equal, while the variances can vary." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig_bl_time = plt.figure(figsize=(10.5, 5), dpi=90)\n", + "axe_bl_time = fig_bl_time.add_subplot(111)\n", + "axe_bl_time.set_autoscalex_on(False)\n", + "def f(center, width):\n", + " lower_bnd = center - width/2\n", + " upper_bnd = center + width/2\n", + " values = data_trimmed[np.logical_and(data_trimmed[\"gen_time\"] <= upper_bnd,\n", + " data_trimmed[\"gen_time\"] >= lower_bnd)]\n", + " axe_bl_time.clear()\n", + " axe_bl_time.set_title(\"Private key bit length, given keygen time $\\in ({}, {})$ {}\".format(int(lower_bnd), int(upper_bnd), sign_disp_unit))\n", + " bl_data = np.array(list(map(lambda x: x.bit_length(), values[\"priv\"])), dtype=np.dtype(\"u2\"))\n", + " plot_hist(axe_bl_time, bl_data, \"private key bit length\", bins=11, range=(bit_size-10, bit_size+1), align=\"left\")\n", + " axe_bl_time.set_xlim((bit_size-10, bit_size))\n", + " fig_bl_time.tight_layout()\n", + "\n", + "center_w = widgets.IntSlider(min=min(data_trimmed[\"gen_time\"]),\n", + " max=max(data_trimmed[\"gen_time\"]),\n", + " step=1,\n", + " value=description_sign_trim.mean,\n", + " continuous_update=False,\n", + " description=\"center {}\".format(sign_disp_unit))\n", + "width_w = widgets.IntSlider(min=1, max=100, continuous_update=False,\n", + " description=\"width {}\".format(sign_disp_unit))\n", + "w = interactive(f, center=center_w,\n", + " width=width_w)\n", + "display(w)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "## Validation\n", "Perform some tests on the produced data and compare to expected results.\n", "\n", @@ -612,7 +669,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "All of the following tests should pass (e.g. be true):" + "All of the following tests should pass (e.g. be true), given a large enough sample:" ] }, { @@ -622,16 +679,26 @@ "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())" + "\n", + "print(\"Private keys are smaller than order:\\t\\t\\t\" + str(max_priv < r))\n", + "print(\"Private keys are larger than prime(if order > prime):\\t\" + str(r <= p or max_priv > p))\n", + "print(\"Private keys reach full bit length of order:\\t\\t\" + str(max_priv.bit_length() == r.bit_length()))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Private key bit length (min, max):\" + str(min(data[\"priv\"]).bit_length()) + \", \" + str(max(data[\"priv\"]).bit_length()))" ] } ], "metadata": { "@webio": { - "lastCommId": "a0b5176ec9b441fc87297b9ed343c5b3", - "lastKernelId": "a6864201-5c88-44d7-8438-ea96f7295d78" + "lastCommId": "bfabd932302644968194449673036179", + "lastKernelId": "b7098475-e3c7-43a2-9851-9b285c0afdc4" }, "hide_input": false, "kernelspec": { diff --git a/util/utils.py b/util/utils.py index 5359988..670e7c2 100644 --- a/util/utils.py +++ b/util/utils.py @@ -1,5 +1,6 @@ import numpy as np from matplotlib import ticker +from math import sqrt, log def hw(i): @@ -31,6 +32,21 @@ def time_scale(data, orig_unit, target_unit, scaling_factor): return (r"$\frac{1}{" + str(scaling_factor) + "}$" if scaling_factor != 1 else "") + units[target_unit][0] +def hist_size_func(choice): + if choice == "sqrt": + return lambda n, xmin, xmax, var, xlower, xupper: int(sqrt(n)) + 1 + elif choice == "sturges": + return lambda n, xmin, xmax, var, xlower, xupper: int(log(n, 2)) + 1 + elif choice == "rice": + return lambda n, xmin, xmax, var, xlower, xupper: int(2 * n**(1/3)) + elif choice == "scott": + return lambda n, xmin, xmax, var, xlower, xupper: (xmax - xmin) // int((3.5 * sqrt(var)) / (n**(1/3))) + elif choice == "fd": + return lambda n, xmin, xmax, var, xlower, xupper: (xmax - xmin) // int(2 * (xupper - xlower) / (n**(1/3))) + else: + return lambda n, xmin, xmax, var, xlower, xupper: hist_size + + def plot_hist(axes, data, xlabel=None, log=False, avg=True, median=True, bins=None, **kwargs): time_max = max(data) time_min = min(data) |
