aboutsummaryrefslogtreecommitdiff
path: root/epare/visualize.ipynb
diff options
context:
space:
mode:
authorJ08nY2025-03-10 16:42:55 +0100
committerJ08nY2025-04-16 12:25:06 +0200
commita05b69373ddd548e52e04b978ef23ef03a448f13 (patch)
treec21834880c218c7ffdbe694cd5e659db12c271af /epare/visualize.ipynb
parente593434e54db0de71b5e1232b693c12d7863ef44 (diff)
downloadECTester-a05b69373ddd548e52e04b978ef23ef03a448f13.tar.gz
ECTester-a05b69373ddd548e52e04b978ef23ef03a448f13.tar.zst
ECTester-a05b69373ddd548e52e04b978ef23ef03a448f13.zip
Diffstat (limited to 'epare/visualize.ipynb')
-rw-r--r--epare/visualize.ipynb692
1 files changed, 692 insertions, 0 deletions
diff --git a/epare/visualize.ipynb b/epare/visualize.ipynb
new file mode 100644
index 0000000..8fa5bb1
--- /dev/null
+++ b/epare/visualize.ipynb
@@ -0,0 +1,692 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3232df80-2a65-47ce-bc77-6a64f44d2404",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pickle\n",
+ "import itertools\n",
+ "\n",
+ "import matplotlib\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "\n",
+ "from collections import Counter\n",
+ "from pathlib import Path\n",
+ "from random import randint\n",
+ "\n",
+ "from bs4 import BeautifulSoup\n",
+ "from tqdm.auto import tqdm, trange\n",
+ "\n",
+ "from common import MultIdent, MultResults"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2130254b-4b88-4928-9fa0-88fa58de9fc7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# All dbl-and-add multipliers from https://github.com/J08nY/pyecsca/blob/master/pyecsca/ec/mult\n",
+ "\n",
+ "window_mults = [\n",
+ " MultIdent(SlidingWindowMultiplier, width=4),\n",
+ " MultIdent(SlidingWindowMultiplier, width=5),\n",
+ " MultIdent(SlidingWindowMultiplier, width=6),\n",
+ " MultIdent(FixedWindowLTRMultiplier, m=2**4),\n",
+ " MultIdent(FixedWindowLTRMultiplier, m=2**5),\n",
+ " MultIdent(FixedWindowLTRMultiplier, m=2**6),\n",
+ " MultIdent(WindowBoothMultiplier, width=4),\n",
+ " MultIdent(WindowBoothMultiplier, width=5),\n",
+ " MultIdent(WindowBoothMultiplier, width=6)\n",
+ "]\n",
+ "naf_mults = [\n",
+ " MultIdent(WindowNAFMultiplier, width=4),\n",
+ " MultIdent(WindowNAFMultiplier, width=5),\n",
+ " MultIdent(WindowNAFMultiplier, width=6),\n",
+ " MultIdent(BinaryNAFMultiplier)\n",
+ "]\n",
+ "comb_mults = [\n",
+ " MultIdent(CombMultiplier, width=4),\n",
+ " MultIdent(CombMultiplier, width=5),\n",
+ " MultIdent(CombMultiplier, width=6),\n",
+ " MultIdent(BGMWMultiplier, width=4),\n",
+ " MultIdent(BGMWMultiplier, width=5),\n",
+ " MultIdent(BGMWMultiplier, width=6)\n",
+ "]\n",
+ "binary_mults = [\n",
+ " MultIdent(LTRMultiplier),\n",
+ " MultIdent(RTLMultiplier),\n",
+ " MultIdent(CoronMultiplier)\n",
+ "]\n",
+ "other_mults = [\n",
+ " MultIdent(FullPrecompMultiplier),\n",
+ " MultIdent(SimpleLadderMultiplier)\n",
+ "]\n",
+ "\n",
+ "with_precomputation = window_mults + naf_mults[:-1] + other_mults[:-1] + comb_mults\n",
+ "\n",
+ "all_mults = window_mults + naf_mults + binary_mults + other_mults + comb_mults"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2df8cd8c-9528-4755-83b5-10ecabaead54",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def divides_any(l: int, small_scalars: set[int]) -> bool:\n",
+ " if l in small_scalars:\n",
+ " return True\n",
+ " for s in small_scalars:\n",
+ " if s%l==0:\n",
+ " return True\n",
+ " return False\n",
+ "\n",
+ "def process_small_scalars(scalar_results: MultResults, divisors: set[int]) -> dict[int, float]:\n",
+ " result = {}\n",
+ " for divisor in tqdm(divisors, leave=False):\n",
+ " count = 0\n",
+ " for smult in scalar_results.multiplications:\n",
+ " if divides_any(divisor, smult):\n",
+ " count += 1\n",
+ " result[divisor] = count / scalar_results.samples\n",
+ " return result\n",
+ "\n",
+ "def merge_probs(*prob_maps: dict[int, float]) -> dict[int, float]:\n",
+ " # Merge two or more maps of \"small-scalar\" -> \"probability\" together by averaging them.\n",
+ " # This is correct if they were collected with the same amount of samples. If the\n",
+ " # amount of samples differs a lot this will not update as much as it should, but will\n",
+ " # update in the correct direction nonetheless.\n",
+ " counter = Counter()\n",
+ " nprobs = len(prob_maps)\n",
+ " for prob_map in prob_maps:\n",
+ " for k, v in prob_map.items():\n",
+ " counter[k] += v\n",
+ " return {k: v / nprobs for k, v in counter.items()}\n",
+ "\n",
+ "def mult_label(mult: MultIdent | ScalarMultiplier) -> str:\n",
+ " if isinstance(mult, ScalarMultiplier):\n",
+ " for attr in (\"width\", \"m\"):\n",
+ " if not hasattr(mult, attr):\n",
+ " continue\n",
+ " return f\"{mult.__class__.__name__}_{getattr(mult, attr)}\"\n",
+ " return mult.__class__.__name__\n",
+ " elif isinstance(mult, MultIdent):\n",
+ " return str(mult)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bab2a086-8b3d-4e76-bf5c-46ea2b617708",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def powers_of(k, max_power=10):\n",
+ " return [k**i for i in range(1, max_power)]\n",
+ "\n",
+ "def prod_combine(one, other):\n",
+ " return [a * b for a, b in itertools.product(one, other)]\n",
+ "\n",
+ "small_primes = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199]\n",
+ "medium_primes = [211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397]\n",
+ "large_primes = [401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]\n",
+ "all_integers = list(range(1, 100))\n",
+ "\n",
+ "all_divisors = small_primes + medium_primes + large_primes #+ powers_of(2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "318ca5ac-66a6-4187-a01f-f0e2d27ba34e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Load\n",
+ "with open(f\"multiples_{category}_{curve}_{bits}\", \"rb\") as f:\n",
+ " multiples_mults = pickle.load(f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4d2a0f19-8275-4db8-b3fc-c930d8ba2177",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "selected_mults = all_mults\n",
+ "selected_divisors = all_divisors"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6b42d25f-6ce1-477a-bc5f-d7c2a8af87a3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "distributions_mults = {}\n",
+ "for mult, results in tqdm(multiples_mults.items()):\n",
+ " distributions_mults[mult] = process_small_scalars(results, selected_divisors)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "906b5d78-b3a4-4cbb-8051-092d411ba735",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plot_mults = selected_mults\n",
+ "plot_divisors = selected_divisors\n",
+ "\n",
+ "colors = {mult:matplotlib.cm.tab20(range(len(plot_mults)))[i] for i,mult in enumerate(plot_mults)}\n",
+ "\n",
+ "fig = plt.subplots(figsize=(36, 12))\n",
+ "\n",
+ "L = len(plot_divisors)\n",
+ "plot_divisors = sorted(plot_divisors)\n",
+ "for mult in plot_mults:\n",
+ " y_values = [distributions_mults[mult][l] for l in plot_divisors]\n",
+ " plt.plot(list(range(L)), y_values, color=colors[mult], label=str(mult))\n",
+ "plt.plot(list(range(L)), var / np.max(var), label=\"cross-mult variance (normalized)\", ls=\"--\", lw=2, color=\"black\")\n",
+ "plt.xlabel(\"divisors\") \n",
+ "plt.ylabel(\"error probability\")\n",
+ "plt.xticks(list(range(L)), plot_divisors, rotation=90)\n",
+ "\n",
+ "plt.grid()\n",
+ "plt.legend()\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/re.png\",dpi=300)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b7fcd473-6cde-4913-9274-ff02f5ddb786",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plot_mults = [mult for mult in selected_mults if mult.klass not in (CombMultiplier, BGMWMultiplier)]\n",
+ "plot_divisors = selected_divisors\n",
+ "\n",
+ "colors = {mult:matplotlib.cm.tab20(range(len(plot_mults)))[i] for i,mult in enumerate(plot_mults)}\n",
+ "\n",
+ "fig = plt.subplots(figsize=(36, 12))\n",
+ "\n",
+ "L = len(plot_divisors)\n",
+ "N = len(plot_mults)\n",
+ "plot_divisors = sorted(plot_divisors)\n",
+ "vals = np.zeros((N, L))\n",
+ "for i, mult in enumerate(plot_mults):\n",
+ " for j, m in enumerate(plot_divisors):\n",
+ " y = distributions_mults[mult][m]\n",
+ " vals[i, j] = y\n",
+ "var = np.var(vals, axis=0)\n",
+ "plt.plot(list(range(L)), var, label=\"cross-mult variance\", ls=\"--\", lw=2, color=\"black\")\n",
+ "\n",
+ "plt.xlabel(\"divisors\")\n",
+ "plt.ylabel(\"variance\")\n",
+ "plt.xticks(list(range(L)), plot_divisors, rotation=90)\n",
+ "\n",
+ "plt.grid()\n",
+ "plt.legend()\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/cross_var.png\",dpi=300)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8454cb7a-5308-43c6-9cd0-5de7946ec72a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# general_distributions = get_general_distributions(selected_divisors, bits, samples)\n",
+ "# general_n_distributions = get_general_n_distributions(selected_divisors, bits, 256, samples)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8eae8df8-0bf8-4a9d-a55e-deea6a9d6b07",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "selected_mults = all_mults#window_mults[0:1]+window_mults[5:6]+naf_mults[1:2]#[mult for mult in all_mults if not mult in comb_mults]\n",
+ "selected_divisors = all_divisors\n",
+ "colors = {mult:matplotlib.cm.tab20(range(len(distributions_mults_10k)))[i] for i,mult in enumerate(distributions_mults_10k)}\n",
+ "\n",
+ "\n",
+ "fig = plt.subplots(figsize =(36, 12)) \n",
+ "\n",
+ "L = len(selected_divisors)\n",
+ "selected_divisors = sorted(selected_divisors)\n",
+ "for mult in distributions_mults_10k:\n",
+ " y_values = [distributions_mults_10k[mult][l] for l in selected_divisors]\n",
+ " plt.plot([l for l in range(L)],y_values,color = colors[mult], label = mult_label(mult))\n",
+ "\n",
+ "# mult = list(fixedwindow_dist.keys())[0]\n",
+ "# plt.plot([l for l in range(L)],[fixedwindow_dist[l] for l in selected_divisors],color = \"pink\", label = mult_label(mult))\n",
+ "\n",
+ "# measured_dist = measured_distribution(library,selected_divisors)\n",
+ "# mes_x, mes_y = [],[]\n",
+ "# for i,l in enumerate(selected_divisors):\n",
+ "# if l in measured_dist:\n",
+ "# mes_y.append(measured_dist[l])\n",
+ "# mes_x.append(i)\n",
+ "# plt.scatter(mes_x,mes_y,color = \"black\", label = library)\n",
+ "\n",
+ "#attempts = 0\n",
+ "#fails =0\n",
+ "#for i in range(51):\n",
+ "# with open(f\"cards/jcop/199_{i}.txt\") as f:\n",
+ "# attempts += f.read().count(\"ALG_EC_SVDP_DH of remote pubkey and local privkey\")+1\n",
+ "# fails += 1\n",
+ "#plt.scatter([selected_divisors.index(199)],[fails/attempts],s=[40],color = \"black\", label = \"jcop\")\n",
+ "\n",
+ "#plt.plot([l for l in range(L)],[general_distributions[l] for l in selected_divisors],color = \"black\", label = \"prime-distribution\")\n",
+ "\n",
+ "\n",
+ "plt.xlabel('divisors') \n",
+ "plt.ylabel(\"prob\") \n",
+ "plt.xticks([r for r in range(L)], selected_divisors)\n",
+ "\n",
+ "plt.legend()\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/re.png\",dpi=300)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d240059f-9ed6-4864-b4bf-525de576272f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "selected_mults = with_precomputation\n",
+ "selected_divisors = all_divisors\n",
+ "colors = {mult:matplotlib.cm.tab20(range(len(selected_mults)))[i] for i,mult in enumerate(selected_mults)}\n",
+ "\n",
+ "\n",
+ "fig = plt.subplots(figsize =(24, 12)) \n",
+ "\n",
+ "L = len(selected_divisors)\n",
+ "selected_divisors = sorted(selected_divisors)\n",
+ "for mult in selected_mults:\n",
+ " plt.plot([l for l in range(L)],[distributions_mults_precomp[mult][l] for l in selected_divisors],color = colors[mult], label = mult_label(mult))\n",
+ "\n",
+ "\n",
+ "#measured_dist = measured_distribution(library,selected_divisors)\n",
+ "#mes_x, mes_y = [],[]\n",
+ "#for i,l in enumerate(selected_divisors):\n",
+ "# if l in measured_dist:\n",
+ "# mes_y.append(measured_dist[l])\n",
+ "# mes_x.append(i)\n",
+ "#plt.scatter(mes_x,mes_y,color = \"black\", label = library)\n",
+ "\n",
+ "\n",
+ "plt.xlabel('divisors') \n",
+ "plt.ylabel(\"prob\") \n",
+ "plt.xticks([r for r in range(L)], selected_divisors)\n",
+ "\n",
+ "plt.legend()\n",
+ "plt.show() "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0da0eed4-a5dc-4dde-9bd1-8b519d02375e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def nok_ecdh(line):\n",
+ " return int(line.split(\";\")[-1].strip(),16)==0\n",
+ "\n",
+ "def measured_distribution(library, selected_divisors):\n",
+ " measured_distribution = {}\n",
+ " counts = {order:0 for order in selected_divisors}\n",
+ " for div in selected_divisors:\n",
+ " errors = 0\n",
+ " with open(f\"./ecdh/{library}/ecdh_{div}.txt\") as f:\n",
+ " for line in f.readlines()[1:]:\n",
+ " if nok_ecdh(line):\n",
+ " errors+=1\n",
+ " counts[div]+=1\n",
+ " measured_distribution[div] = errors\n",
+ " \n",
+ " for o,v in measured_distribution.items():\n",
+ " if counts[o]!=0:\n",
+ " measured_distribution[o] = v/counts[o]\n",
+ " return measured_distribution"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6f8b83e3-7e2e-409a-82bd-7d44316236c6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "selected_mults = other_mults[:1]+binary_mults[:1]+comb_mults[:1]+window_mults[:1]\n",
+ "selected_divisors = small_primes#all_divisors\n",
+ "library = \"tomcrypt\"\n",
+ "colors = {mult:matplotlib.cm.tab20(range(len(selected_mults)))[i] for i,mult in enumerate(selected_mults)}\n",
+ "\n",
+ "fig = plt.subplots(figsize =(24, 12)) \n",
+ "\n",
+ "L = len(selected_divisors)\n",
+ "selected_divisors = sorted(selected_divisors)\n",
+ "for mult in selected_mults:\n",
+ " plt.plot([l for l in range(L)],[distributions_mults[mult][l] for l in selected_divisors],color = colors[mult], label = mult_label(mult))\n",
+ "\n",
+ "\n",
+ "measured_dist = measured_distribution(library,selected_divisors)\n",
+ "mes_x, mes_y = [],[]\n",
+ "for i,l in enumerate(selected_divisors):\n",
+ " if l in measured_dist:\n",
+ " mes_y.append(measured_dist[l])\n",
+ " mes_x.append(i)\n",
+ "plt.scatter(mes_x,mes_y,color = \"black\", label = library)\n",
+ "\n",
+ "\n",
+ "plt.xlabel('divisors') \n",
+ "plt.ylabel(\"prob\") \n",
+ "plt.xticks([r for r in range(L)], selected_divisors)\n",
+ "plt.legend(loc=\"upper right\")\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/{library}/re.png\",dpi=300)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b7936e5b-76d2-410f-82b1-36333071bd12",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "selected_mults = [mult for mult in with_precomputation if mult in comb_mults]\n",
+ "selected_divisors = small_primes#all_divisors\n",
+ "library = \"mbedtls\"\n",
+ "colors = {mult:matplotlib.cm.tab20(range(len(selected_mults)))[i] for i,mult in enumerate(selected_mults)}\n",
+ "\n",
+ "fig = plt.subplots(figsize =(24, 12)) \n",
+ "\n",
+ "L = len(selected_divisors)\n",
+ "selected_divisors = sorted(selected_divisors)\n",
+ "for mult in selected_mults:\n",
+ " plt.plot([l for l in range(L)],[distributions_mults_precomp[mult][l] for l in selected_divisors],color = colors[mult], label = mult_label(mult))\n",
+ "\n",
+ "\n",
+ "measured_dist = measured_distribution(library,selected_divisors)\n",
+ "mes_x, mes_y = [],[]\n",
+ "for i,l in enumerate(selected_divisors):\n",
+ " if l in measured_dist:\n",
+ " mes_y.append(measured_dist[l])\n",
+ " mes_x.append(i)\n",
+ "plt.scatter(mes_x,mes_y,color = \"black\", label = library)\n",
+ "\n",
+ "plt.xlabel('divisors') \n",
+ "plt.ylabel(\"prob\") \n",
+ "plt.xticks([r for r in range(L)], selected_divisors)\n",
+ "plt.legend()\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/{library}/re.png\",dpi=300)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dbdd0219-3937-4ef3-8cb3-b90f03af9977",
+ "metadata": {},
+ "source": [
+ "BouncyCastle\n",
+ " - WindowBooth-5?\n",
+ "\n",
+ "Mbedtls\n",
+ " - CombMultiplier-4\n",
+ " - confirmed in library\n",
+ " \n",
+ "tomcrypt\n",
+ " - ladder or coron\n",
+ " - ladder confirmed in library\n",
+ "\n",
+ "OpenSSL, LibreSSL, Botan, Crypto++ and IPPCP followed the general distribution of divisibility by the primes. So they have some countermeasure.\n",
+ "\n",
+ "Note that some libraries for some orders output \"Invalid algorithm parameter: Not supported.\". For libcrypt, SunEC and Nettle it happened for all orders.\n",
+ "BoringSSL\n",
+ " - \"Invalid algorithm parameter: Error creating EC_GROUP, EC_GROUP_set_generator.\"\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "34609ae2-fa8c-4437-a601-cd25a0708a19",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def scatter(library, color):\n",
+ " measured_dist = measured_distribution(library,selected_divisors)\n",
+ " mes_x, mes_y = [],[]\n",
+ " for i,l in enumerate(selected_divisors):\n",
+ " if l in measured_dist:\n",
+ " mes_y.append(measured_dist[l])\n",
+ " mes_x.append(i)\n",
+ " plt.scatter(mes_x,mes_y,color = color, label = library)\n",
+ "\n",
+ "selected_divisors = small_primes#all_divisors\n",
+ "\n",
+ "fig = plt.subplots(figsize =(24, 12)) \n",
+ "\n",
+ "L = len(selected_divisors)\n",
+ "\n",
+ "colors = matplotlib.cm.tab20(range(6))\n",
+ "scatter(\"openssl\",colors[0])\n",
+ "scatter(\"libressl\",colors[1])\n",
+ "scatter(\"botan\",colors[2])\n",
+ "scatter(\"Crypto++\",colors[3])\n",
+ "scatter(\"ippcp\",colors[4])\n",
+ "\n",
+ "plt.plot([l for l in range(L)],[general_distributions[l] for l in selected_divisors],color = colors[5], label = \"prime-distribution\")\n",
+ "\n",
+ "plt.xlabel('divisors') \n",
+ "plt.ylabel(\"prob\") \n",
+ "plt.xticks([r for r in range(L)], selected_divisors)\n",
+ "plt.legend()\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/resistant.png\",dpi=300)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1f403fa3-880d-45a8-aaf3-964b0fbc38d7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def scatter(library, color):\n",
+ " measured_dist = measured_distribution(library,selected_divisors)\n",
+ " mes_x, mes_y = [],[]\n",
+ " for i,l in enumerate(selected_divisors):\n",
+ " if l in measured_dist:\n",
+ " mes_y.append(measured_dist[l])\n",
+ " mes_x.append(i)\n",
+ " # plt.scatter(mes_x,mes_y,color = color, label = library)\n",
+ " plt.plot(mes_x,mes_y,color = color, linewidth = 1, label = library)\n",
+ "\n",
+ "selected_divisors = small_primes[:12]#all_divisors\n",
+ "\n",
+ "fig = plt.subplots(figsize =(10, 4)) \n",
+ "\n",
+ "L = len(selected_divisors)\n",
+ "\n",
+ "colors = matplotlib.cm.tab20(range(9))\n",
+ "scatter(\"openssl\",colors[0])\n",
+ "scatter(\"libressl\",colors[1])\n",
+ "scatter(\"botan\",colors[2])\n",
+ "scatter(\"Crypto++\",colors[3])\n",
+ "scatter(\"mbedtls\",colors[4])\n",
+ "scatter(\"libressl\",colors[5])\n",
+ "scatter(\"BouncyCastle\",colors[6])\n",
+ "scatter(\"tomcrypt\",colors[7])\n",
+ "scatter(\"ippcp\",colors[8])\n",
+ "\n",
+ "\n",
+ "# plt.plot([l for l in range(L)],[general_distributions[l] for l in selected_divisors],color = colors[9], label = \"divison-distribution\")\n",
+ "\n",
+ "plt.xlabel('Input point order',fontsize=15) \n",
+ "plt.ylabel(\"Error rate\",fontsize=15) \n",
+ "plt.xticks([r for r in range(L)], [v if i%1==0 else \"\" for i,v in enumerate(selected_divisors)])\n",
+ "plt.legend(loc=\"center right\",prop={'size': 11})\n",
+ "plt.tight_layout()\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/lib_dists.png\",dpi=300)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a0415861-c9ee-4420-bb82-6fda216d401c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def bars(library, color,shift,width):\n",
+ " measured_dist = measured_distribution(library,selected_divisors)\n",
+ " mes_x, mes_y = [],[]\n",
+ " for i,l in enumerate(selected_divisors):\n",
+ " offset = width*shift\n",
+ " if l in measured_dist:\n",
+ " mes_y.append(measured_dist[l])\n",
+ " mes_x.append(2*i+offset)\n",
+ " plt.bar(mes_x,mes_y,width=0.1,color = color,align ='center', label = labels.get(library,library))\n",
+ "\n",
+ "selected_divisors = small_primes[:12]#all_divisors\n",
+ "\n",
+ "fig = plt.subplots(figsize =(10, 4)) \n",
+ "\n",
+ "L = len(selected_divisors)\n",
+ "\n",
+ "colors = matplotlib.cm.tab20(range(9))\n",
+ "width = 0.2\n",
+ "for i,lib in enumerate((\"openssl\",\"libressl\",\"botan\",\"Crypto++\",\"mbedtls\",\"BouncyCastle\",\"tomcrypt\",\"ippcp\")):\n",
+ " bars(lib,colors[i],i,width)\n",
+ "\n",
+ "\n",
+ "plt.plot([2*l+4*width for l in range(L)],[general_distributions[l] for l in selected_divisors],color = colors[8], label = \"expected distribution\")\n",
+ "\n",
+ "plt.xlabel('Input point order',fontsize=15) \n",
+ "plt.ylabel(\"Error rate\",fontsize=15) \n",
+ "plt.xticks([2*r+4*width for r in range(L)], [v if i%1==0 else \"\" for i,v in enumerate(selected_divisors)])\n",
+ "plt.legend(loc=\"upper right\",prop={'size': 11})\n",
+ "plt.tight_layout()\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/lib_dists.png\",dpi=300)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e5f036c8-3d47-4105-9a67-79b2b8e1ecdb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from math import sqrt\n",
+ "\n",
+ "selected_mults = all_mults#window_mults[0:1]+window_mults[5:6]+naf_mults[1:2]#[mult for mult in all_mults if not mult in comb_mults]\n",
+ "selected_divisors = small_primes#ll_divisors\n",
+ "colors = {mult:matplotlib.cm.tab20(range(len(selected_mults)))[i] for i,mult in enumerate(selected_mults)}\n",
+ "\n",
+ "\n",
+ "fig = plt.subplots(figsize =(30, 20)) \n",
+ "\n",
+ "L = len(selected_divisors)\n",
+ "selected_divisors = sorted(selected_divisors)\n",
+ "for mult in selected_mults:\n",
+ " y_values,y_values_mstd, y_values_pstd = [],[],[]\n",
+ " for l in selected_divisors:\n",
+ " p = distributions_mults[mult][l]\n",
+ " y_values.append(1/p)\n",
+ " y_values_mstd.append(1/p-sqrt((1-p)/p**2))\n",
+ " y_values_pstd.append(1/p+sqrt((1-p)/p**2))\n",
+ " plt.plot([l for l in range(L)],y_values,color = colors[mult], label = mult_label(mult))\n",
+ " plt.fill_between([l for l in range(L)], y_values_mstd , y_values_pstd, alpha = 0.1, color = colors[mult])\n",
+ " \n",
+ "# mult = list(fixedwindow_dist.keys())[0]\n",
+ "# plt.plot([l for l in range(L)],[fixedwindow_dist[l] for l in selected_divisors],color = \"pink\", label = mult_label(mult))\n",
+ "\n",
+ "# measured_dist = measured_distribution(library,selected_divisors)\n",
+ "# mes_x, mes_y = [],[]\n",
+ "# for i,l in enumerate(selected_divisors):\n",
+ "# if l in measured_dist:\n",
+ "# mes_y.append(measured_dist[l])\n",
+ "# mes_x.append(i)\n",
+ "# plt.scatter(mes_x,mes_y,color = \"black\", label = library)\n",
+ "\n",
+ "plt.plot([l for l in range(L)],[1/general_distributions[l] for l in selected_divisors],color = \"black\", label = \"prime-distribution\")\n",
+ "\n",
+ "steps_dist = {}\n",
+ "for i in range(51):\n",
+ " with open(f\"cards/jcop/199_{i}.txt\") as f:\n",
+ " steps = f.read().count(\"ALG_EC_SVDP_DH of remote pubkey and local privkey\")\n",
+ " if not steps in steps_dist:\n",
+ " steps_dist[steps] = 0\n",
+ " steps_dist[steps]+=1\n",
+ "ys = sorted(list(steps_dist.keys()))\n",
+ "plt.scatter([selected_divisors.index(199)]*len(ys),ys, s=[steps_dist[y]*20 for y in ys],color=\"black\")\n",
+ "for i, y in enumerate(ys):\n",
+ " plt.annotate(str(steps_dist[y]), (selected_divisors.index(199)-1, y))\n",
+ "avg = 0\n",
+ "for s,c in steps_dist.items():\n",
+ " avg+=s*c\n",
+ "avg = avg/sum(steps_dist.values())\n",
+ "plt.scatter([selected_divisors.index(199)],[avg], s=[30],color=\"yellow\")\n",
+ " \n",
+ "plt.xlabel('divisors') \n",
+ "plt.ylabel(\"prob\") \n",
+ "plt.yticks(range(12))\n",
+ "plt.xticks([r for r in range(L)], selected_divisors)\n",
+ "\n",
+ "plt.legend()\n",
+ "plt.show() \n",
+ "fig[0].savefig(f\"graphs/re.png\",dpi=300)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "37a64963-e63a-4c74-8414-6d29482e7151",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}