diff options
| author | J08nY | 2025-03-15 00:52:44 +0100 |
|---|---|---|
| committer | J08nY | 2025-04-16 12:25:06 +0200 |
| commit | d1e7eae1889a054d2aca398c0b8537de94263556 (patch) | |
| tree | 4c06e567c91dce77657e108a19d4b7ed123a6f09 | |
| parent | d32571bf09da8963b3597dca95818f300c96223d (diff) | |
| download | ECTester-d1e7eae1889a054d2aca398c0b8537de94263556.tar.gz ECTester-d1e7eae1889a054d2aca398c0b8537de94263556.tar.zst ECTester-d1e7eae1889a054d2aca398c0b8537de94263556.zip | |
| -rw-r--r-- | epare/collect_leia.ipynb | 230 | ||||
| -rw-r--r-- | epare/simulate.ipynb | 17 | ||||
| -rw-r--r-- | epare/visualize.ipynb | 680 |
3 files changed, 367 insertions, 560 deletions
diff --git a/epare/collect_leia.ipynb b/epare/collect_leia.ipynb index e54e643..00d2efc 100644 --- a/epare/collect_leia.ipynb +++ b/epare/collect_leia.ipynb @@ -1,6 +1,14 @@ { "cells": [ { + "cell_type": "markdown", + "id": "fde96d6a-0281-4ba2-ae2f-447cb6a625f0", + "metadata": {}, + "source": [ + "# Power-tracing smartcards using LEIA" + ] + }, + { "cell_type": "code", "execution_count": null, "id": "eab24cb8-af40-4cc1-be5f-f120fe9932ee", @@ -11,7 +19,7 @@ "from pyecsca.ec.params import load_params_ectester\n", "from pyecsca.sca.scope.picoscope_sdk import PS6000Scope\n", "from pyecsca.sca.trace import Trace\n", - "from pyecsca.sca.trace.plot import plot_trace\n", + "from pyecsca.sca.trace.plot import plot_trace, plot_traces\n", "from pyecsca.sca.scope import SampleType\n", "\n", "import numpy as np\n", @@ -21,7 +29,7 @@ "import holoviews as hv\n", "\n", "hv.extension(\"bokeh\")\n", - "%opts RGB [height=600, responsive=True]" + "%opts RGB [height=700, responsive=True]" ] }, { @@ -31,73 +39,132 @@ "metadata": {}, "outputs": [], "source": [ - "sl = LEIA()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "885fba43-7546-48ba-bff4-b6314fd642e6", - "metadata": {}, - "outputs": [], - "source": [ + "sl = LEIA()\n", "ectester = ECTesterTargetLEIA(sl)" ] }, { "cell_type": "code", "execution_count": null, - "id": "8c33b783-7a7e-45f4-9e91-d3df54e1abe0", + "id": "07369045-7eee-4e85-ac4e-37e5396fd880", "metadata": {}, "outputs": [], "source": [ - "scope = PS6000Scope()" + "ectester.connect()" ] }, { "cell_type": "code", "execution_count": null, - "id": "729688c3-d448-4d1a-80c4-666680fcca35", + "id": "89ed5db7-fbbb-4b32-89a5-6486204feed6", "metadata": {}, "outputs": [], "source": [ - "scope.open()" + "atr = ectester.atr\n", + "print(atr, atr.hex())\n", + "card_map = {\n", + " \"3bd518ff8191fe1fc38073c8211309\": \"A1\",\n", + " \"3bb89600c00831fe45ffff1154305023006a\": \"I1\",\n", + " \"3bfe1800008031fe45803180664090a5102e1083019000f2\": \"I2\",\n", + " \"3bf81800ff8131fe454a434f507632343143\": \"N1\",\n", + " \"3bf81300008131fe454a434f5076323431b7\": \"N2N9\",\n", + " \"3b9495810146545601c4\": \"N4\",\n", + " \"3bd518ff8191fe1fc38073c821100a\": \"N6\",\n", + "}\n", + "card = card_map[atr.hex()]\n", + "print(card)" ] }, { "cell_type": "code", "execution_count": null, - "id": "23037143-e39c-4dd6-bf65-9cdcb0d7b266", + "id": "8c33b783-7a7e-45f4-9e91-d3df54e1abe0", "metadata": {}, "outputs": [], "source": [ - "print(scope.get_variant())\n", - "actual_freq, n_samples = scope.setup_frequency(frequency=250_000_000, pretrig=0, posttrig=150_000_000)\n", - "scope.setup_channel(channel=\"A\", coupling=\"DC\", range=1, offset=0, enable=True)\n", - "scope.setup_channel(channel=\"B\", coupling=\"DC\", range=0.1, offset=-0.4, enable=True)\n", - "scope.setup_trigger(channel=\"A\", threshold=0.2, direction=\"rising\", delay=0, timeout=5000, enable=True)\n", - "scope.setup_capture(channel=\"B\", enable=True)\n", - "print(actual_freq, n_samples)" + "scope = PS6000Scope()" ] }, { "cell_type": "code", "execution_count": null, - "id": "07369045-7eee-4e85-ac4e-37e5396fd880", + "id": "729688c3-d448-4d1a-80c4-666680fcca35", "metadata": {}, "outputs": [], "source": [ - "ectester.connect()" + "scope.open()" ] }, { "cell_type": "code", "execution_count": null, - "id": "89ed5db7-fbbb-4b32-89a5-6486204feed6", + "id": "23037143-e39c-4dd6-bf65-9cdcb0d7b266", "metadata": {}, "outputs": [], "source": [ - "ectester.atr" + "print(scope.get_variant())\n", + "if card == \"A1\":\n", + " # Athena IDProtect\n", + " # 35M for keygen\n", + " # 13M for ecdh\n", + " actual_freq, n_samples = scope.setup_frequency(frequency=50_000_000, pretrig=0, posttrig=35_000_000)\n", + " scope.setup_channel(channel=\"A\", coupling=\"DC\", range=1, offset=0, enable=True)\n", + " scope.setup_channel(channel=\"B\", coupling=\"DC_50\", range=0.2, offset=-0.24, enable=True)\n", + " scope.setup_trigger(channel=\"A\", threshold=0.2, direction=\"rising\", delay=0, timeout=5000, enable=True)\n", + " scope.setup_capture(channel=\"B\", enable=True)\n", + "elif card == \"I1\":\n", + " # Infineon SECORA\n", + " # 6M for keygen\n", + " # 3M for ecdh\n", + " actual_freq, n_samples = scope.setup_frequency(frequency=50_000_000, pretrig=0, posttrig=6_000_000)\n", + " scope.setup_channel(channel=\"A\", coupling=\"DC\", range=1, offset=0, enable=True)\n", + " scope.setup_channel(channel=\"B\", coupling=\"DC_50\", range=0.2, offset=-0.25, enable=True)\n", + " scope.setup_trigger(channel=\"A\", threshold=0.2, direction=\"rising\", delay=0, timeout=5000, enable=True)\n", + " scope.setup_capture(channel=\"B\", enable=True)\n", + "elif card == \"I2\":\n", + " # Infineon CJTOP SLJ 52GLA0890AL M84\n", + " actual_freq, n_samples = scope.setup_frequency(frequency=50_000_000, pretrig=0, posttrig=15_000_000)\n", + " scope.setup_channel(channel=\"A\", coupling=\"DC\", range=1, offset=0, enable=True)\n", + " scope.setup_channel(channel=\"B\", coupling=\"DC_50\", range=0.1, offset=-0.15, enable=True)\n", + " scope.setup_trigger(channel=\"A\", threshold=0.2, direction=\"rising\", delay=0, timeout=5000, enable=True)\n", + " scope.setup_capture(channel=\"B\", enable=True)\n", + "elif card == \"N1\":\n", + " # NXP J3A081\n", + " # 30M for keygen (first), then 10M for subsequent\n", + " # 10M for ecdh\n", + " actual_freq, n_samples = scope.setup_frequency(frequency=50_000_000, pretrig=0, posttrig=30_000_000)\n", + " scope.setup_channel(channel=\"A\", coupling=\"DC\", range=1, offset=0, enable=True)\n", + " scope.setup_channel(channel=\"B\", coupling=\"DC_50\", range=0.05, offset=-0.18, enable=True)\n", + " scope.setup_trigger(channel=\"A\", threshold=0.2, direction=\"rising\", delay=0, timeout=5000, enable=True)\n", + " scope.setup_capture(channel=\"B\", enable=True)\n", + "elif card == \"N2N9\":\n", + " # NXP JCOP v2.4.1R3\n", + " actual_freq, n_samples = scope.setup_frequency(frequency=50_000_000, pretrig=0, posttrig=30_000_000)\n", + " scope.setup_channel(channel=\"A\", coupling=\"DC\", range=1, offset=0, enable=True)\n", + " scope.setup_channel(channel=\"B\", coupling=\"DC_50\", range=0.05, offset=-0.280, enable=True)\n", + " scope.setup_trigger(channel=\"A\", threshold=0.2, direction=\"rising\", delay=0, timeout=5000, enable=True)\n", + " scope.setup_capture(channel=\"B\", enable=True)\n", + "elif card == \"N4\":\n", + " # NXP J3H145\n", + " # 15M for keygen\n", + " # 10M for ecdh\n", + " actual_freq, n_samples = scope.setup_frequency(frequency=50_000_000, pretrig=0, posttrig=5_000_000)\n", + " scope.setup_channel(channel=\"A\", coupling=\"DC\", range=1, offset=0, enable=True)\n", + " scope.setup_channel(channel=\"B\", coupling=\"DC_50\", range=0.2, offset=-0.160, enable=True)\n", + " scope.setup_trigger(channel=\"A\", threshold=0.2, direction=\"rising\", delay=0, timeout=5000, enable=True)\n", + " scope.setup_capture(channel=\"B\", enable=True)\n", + "elif card == \"N6\":\n", + " # NXP JCOP4\n", + " # 3M for keygen\n", + " # 3M for ECDH\n", + " actual_freq, n_samples = scope.setup_frequency(frequency=50_000_000, pretrig=0, posttrig=3_000_000)\n", + " scope.setup_channel(channel=\"A\", coupling=\"DC\", range=1, offset=0, enable=True)\n", + " scope.setup_channel(channel=\"B\", coupling=\"DC_50\", range=0.2, offset=-0.170, enable=True)\n", + " scope.setup_trigger(channel=\"A\", threshold=0.2, direction=\"rising\", delay=0, timeout=5000, enable=True)\n", + " scope.setup_capture(channel=\"B\", enable=True)\n", + "\n", + "\n", + "print(actual_freq, n_samples)" ] }, { @@ -128,7 +195,7 @@ "outputs": [], "source": [ "ectester.allocate(KeypairEnum.KEYPAIR_LOCAL,\n", - " KeyBuildEnum.BUILD_KEYPAIR,\n", + " KeyBuildEnum.BUILD_KEYBUILDER | KeyBuildEnum.BUILD_KEYPAIR,\n", " 256,\n", " KeyClassEnum.ALG_EC_FP)" ] @@ -150,7 +217,7 @@ "metadata": {}, "outputs": [], "source": [ - "params = load_params_ectester(\"../common/src/main/resources/cz/crcs/ectester/data/secg/secp256r1.csv\", \"affine\")" + "params = load_params_ectester(\"curves/curves_full_order/cofactor256p313_full.csv\", \"affine\")" ] }, { @@ -214,7 +281,7 @@ "metadata": {}, "outputs": [], "source": [ - "trace_gen = scope.retrieve(\"B\", SampleType.Volt)" + "trace_gen = scope.retrieve(\"B\", SampleType.Raw)" ] }, { @@ -241,6 +308,22 @@ { "cell_type": "code", "execution_count": null, + "id": "f4c1df63-4da3-4693-9aaa-217e4a9314f5", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"curves/cofactor_points/point_313.csv\", \"r\") as f:\n", + " line = f.read()\n", + " sx, sy = line.split(\",\")\n", + " bx = bytes.fromhex(sx[2:])\n", + " by = bytes.fromhex(sy[2:])\n", + " point = bytes([0x04]) + bx + by\n", + " print(point.hex())" + ] + }, + { + "cell_type": "code", + "execution_count": null, "id": "ad17301a-902f-48e9-936e-f553a1a8f006", "metadata": {}, "outputs": [], @@ -249,7 +332,7 @@ " True,\n", " TransformationEnum.NONE,\n", " KeyAgreementEnum.ALG_EC_SVDP_DH,\n", - " bytes.fromhex(\"046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5\")) # pubkey as bytes" + " point) # pubkey as bytes" ] }, { @@ -285,6 +368,77 @@ { "cell_type": "code", "execution_count": null, + "id": "6c46be4f-8901-4b29-a30e-71ac28bafcd9", + "metadata": {}, + "outputs": [], + "source": [ + "from pyecsca.sca.trace.edit import pad, trim" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1d4b775e-fa7d-48aa-bb24-bec7450c8114", + "metadata": {}, + "outputs": [], + "source": [ + "trim?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7164dab5-090f-4a6a-9ce6-8e252e71af76", + "metadata": {}, + "outputs": [], + "source": [ + "plot_traces(ecdh_ok, pad(trim(trace_ecdh, 0, len(trace_ecdh) -363700), (363700, 0)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0395b2aa-3c00-4068-8179-039e7e5ad039", + "metadata": {}, + "outputs": [], + "source": [ + "from scipy import signal\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1b63e6d3-8488-4c13-91fa-388318e8e1bc", + "metadata": {}, + "outputs": [], + "source": [ + "corr = signal.correlate(trace_ecdh.samples, trace_ecdh.samples, mode=\"full\")\n", + "lags = signal.correlation_lags(trace_ecdh.samples.size, trace_ecdh.samples.size, mode=\"full\")\n", + "lag = lags[np.argmax(corr)]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6fbd522-c9db-4dbc-bd05-109ba3d3fdf9", + "metadata": {}, + "outputs": [], + "source": [ + "plot_trace(Trace(corr))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a910cc9-80bd-4c74-a36a-56804aea42e1", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, "id": "195ed167-8925-44c9-b0fb-6e207f8fdf8a", "metadata": {}, "outputs": [], @@ -326,7 +480,17 @@ { "cell_type": "code", "execution_count": null, - "id": "2c62eccf-eae1-48be-b562-222504e8e6cf", + "id": "d93ce9cd-1516-4e32-9fed-94a19fac23f4", + "metadata": {}, + "outputs": [], + "source": [ + "from pyecsca.sca.trace.plot import plot_trace, plot_traces" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45f2a8ab-af15-46f9-904e-76e5eeb08978", "metadata": {}, "outputs": [], "source": [] diff --git a/epare/simulate.ipynb b/epare/simulate.ipynb index 4a0a07a..89a5533 100644 --- a/epare/simulate.ipynb +++ b/epare/simulate.ipynb @@ -89,10 +89,11 @@ "def get_small_scalar_multiples(mult: MultIdent,\n", " params: DomainParameters,\n", " bits: int,\n", - " samples: int = 1000,\n", + " samples: int = 100,\n", " use_init: bool = True,\n", " use_multiply: bool = True,\n", - " seed: bytes | None = None) -> MultResults:\n", + " seed: bytes | None = None,\n", + " kind: str = \"precomp+necessary\") -> MultResults:\n", " from pyecsca.sca.re.rpa import multiples_computed\n", " import random\n", " \n", @@ -110,7 +111,7 @@ "\n", " for scalar in scalars:\n", " # Use a list for less memory usage.\n", - " results.append(list(multiples_computed(scalar, params, mult.klass, mult.partial, use_init, use_multiply)))\n", + " results.append(list(multiples_computed(scalar, params, mult.klass, mult.partial, use_init, use_multiply, kind=kind)))\n", " return MultResults(results, samples)" ] }, @@ -134,7 +135,7 @@ "params = get_params(category, curve, \"projective\")\n", "num_workers = 20\n", "bits = params.order.bit_length()\n", - "samples = 1000\n", + "samples = 100\n", "selected_mults = all_mults" ] }, @@ -166,7 +167,7 @@ " for mult, future in tqdm(pool.as_completed(), desc=\"Computing small scalar distributions.\", total=len(pool.tasks)):\n", " print(f\"Got {mult}.\")\n", " if error := future.exception():\n", - " print(error)\n", + " print(\"Error!\", error)\n", " continue\n", " res = future.result()\n", " if mult not in multiples_mults:\n", @@ -188,7 +189,9 @@ "metadata": {}, "source": [ "### Load\n", - "Beware, the following load with try to load all chunks into memory, that will be very large." + "**Beware**, the following load with try to load all chunks into memory, that will be very large.\n", + "\n", + "You probably dont want to run this." ] }, { @@ -212,7 +215,7 @@ { "cell_type": "code", "execution_count": null, - "id": "264385f2-0f58-4f18-bfc2-61f2c5b6e5c8", + "id": "11b447f2-71ab-417e-a856-1724788cfc91", "metadata": {}, "outputs": [], "source": [] diff --git a/epare/visualize.ipynb b/epare/visualize.ipynb index 4b74e30..743c35f 100644 --- a/epare/visualize.ipynb +++ b/epare/visualize.ipynb @@ -1,6 +1,14 @@ { "cells": [ { + "cell_type": "markdown", + "id": "52a95c74-8fc0-4021-a8e9-8587ff6f1d9e", + "metadata": {}, + "source": [ + "# Visualizing prob-maps" + ] + }, + { "cell_type": "code", "execution_count": null, "id": "3232df80-2a65-47ce-bc77-6a64f44d2404", @@ -33,6 +41,15 @@ ] }, { + "cell_type": "markdown", + "id": "4273bd5e-0ec6-4e5c-b63e-74cc325a8ece", + "metadata": {}, + "source": [ + "## Setup\n", + "Setup some plotting and the computations of prob-maps out of the small scalar data and divisors." + ] + }, + { "cell_type": "code", "execution_count": null, "id": "e89e66dc-4a9b-4320-8612-a8fa9af04b69", @@ -42,14 +59,23 @@ "# Setup the ticks and colors deterministically.\n", "mult_klasses = sorted(list(set(map(lambda mult: mult.klass, all_mults))), key=lambda klass: klass.__name__)\n", "mult_kwarg_map = {klass: 0 for klass in mult_klasses}\n", + "mult_cm_map = {mult: 0 for mult in all_mults}\n", "mult_colors = matplotlib.cm.tab20(range(len(mult_klasses)))\n", "mult_styles = ['-', '--', '-.', ':', (5, (10, 3)), (0, (5, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 1, 1, 1)), (0, (1, 1)), (0, (3, 10, 1, 10))]\n", + "mult_markers = [None, \"o\", \"+\", \"*\", \"^\"]\n", "colors = {}\n", "styles = {}\n", + "markers = {}\n", "for mult in all_mults:\n", - " colors[mult] = mult_colors[mult_klasses.index(mult.klass)]\n", - " styles[mult] = mult_styles[mult_kwarg_map[mult.klass]]\n", - " mult_kwarg_map[mult.klass] += 1" + " color = mult_colors[mult_klasses.index(mult.klass) % len(mult_colors)]\n", + " style = mult_styles[mult_kwarg_map[mult.klass] % len(mult_styles)]\n", + " mult_kwarg_map[mult.klass] += 1\n", + " for cm in (None, \"gsr\", \"additive\", \"multiplicative\", \"euclidean\"):\n", + " mwc = mult.with_countermeasure(cm)\n", + " colors[mwc] = color\n", + " styles[mwc] = style\n", + " markers[mwc] = mult_markers[mult_cm_map[mult] % len(mult_markers)]\n", + " mult_cm_map[mult] += 1" ] }, { @@ -67,13 +93,30 @@ "\n", "def process_small_scalars(scalar_results: MultResults, divisors: set[int]) -> ProbMap:\n", " result = {}\n", - " for divisor in tqdm(divisors, leave=False):\n", + " for divisor in divisors:\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 ProbMap(result, scalar_results.samples)" + " return ProbMap(result, scalar_results.samples)\n", + "\n", + "def load_chunk(fname: str, divisors: set[int]) -> dict[MultIdent, ProbMap]:\n", + " with open(fname, \"rb\") as f:\n", + " multiples = pickle.load(f)\n", + " res = {}\n", + " for mult, results in multiples.items():\n", + " res[mult] = process_small_scalars(results, divisors)\n", + " return res" + ] + }, + { + "cell_type": "markdown", + "id": "2596562f-8a6a-4a25-ae82-a6b9562d8a40", + "metadata": {}, + "source": [ + "## Divisors\n", + "The cell below contains some interesting divisors for distinguishing scalarmults." ] }, { @@ -106,11 +149,24 @@ " \"all_even\": all_even,\n", " \"all_odd\": all_odd,\n", " \"powers_of_2\": powers_of(2),\n", - " \"powers_of_2_large\": powers_of(2, 130),\n", - " \"powers_of_2_large_p1\": [i+1 for i in powers_of(2, 130)],\n", + " \"powers_of_2_large\": powers_of(2, 140),\n", + " \"powers_of_2_large_3\": [i * 3 for i in powers_of(2, 140)],\n", + " \"powers_of_2_large_p1\": [i + 1 for i in powers_of(2, 140)],\n", + " \"powers_of_2_large_m1\": [i - 1 for i in powers_of(2, 140)],\n", + " \"powers_of_2_large_pmautobus\": sorted(set([i+j for i in powers_of(2, 140) for j in range(-8,8) if i+j > 0])),\n", " \"powers_of_3\": powers_of(3),\n", "}\n", - "divisor_map[\"all\"] = list(sorted(set().union(*[v for v in divisor_map.values()])))" + "divisor_map[\"all\"] = list(sorted(set().union(*[v for v in divisor_map.values()])))\n", + "for d, ds in divisor_map.items():\n", + " print(d, len(ds))" + ] + }, + { + "cell_type": "markdown", + "id": "51aa1d77-2ea5-49b4-8d2b-c73b88947430", + "metadata": {}, + "source": [ + "Even though we list `secp256r1` here, it is only an API choice, the curve is not used for anything. The number 256 might as well be in its place." ] }, { @@ -124,7 +180,15 @@ "curve = \"secp256r1\"\n", "params = get_params(category, curve, \"projective\")\n", "bits = params.order.bit_length()\n", - "num_workers = 10" + "num_workers = 28" + ] + }, + { + "cell_type": "markdown", + "id": "5b427252-a3ff-4a55-940c-3c8659caa799", + "metadata": {}, + "source": [ + "Select the mults you want to compute the prob-maps for here as well as a set of divisors. It is good to set `all` here, compute the prob-maps for all the divisors, save them and they continue with visualizing them on subsets of divisors." ] }, { @@ -135,7 +199,7 @@ "outputs": [], "source": [ "selected_mults = all_mults\n", - "divisor_name = \"powers_of_2_large_p1\"\n", + "divisor_name = \"all\"\n", "selected_divisors = divisor_map[divisor_name]" ] }, @@ -147,571 +211,147 @@ "outputs": [], "source": [ "distributions_mults = {}\n", - "files = tqdm(glob.glob(f\"multiples_{category}_{curve}_{bits}_chunk*.pickle\"))\n", + "files = sorted(glob.glob(f\"multiples_{category}_{curve}_{bits}_ctr_chunk*.pickle\"))\n", "with TaskExecutor(max_workers=num_workers) as pool:\n", " for fname in files:\n", - " files.set_postfix_str(fname)\n", - " with open(fname, \"rb\") as f:\n", - " multiples_loaded = pickle.load(f)\n", - " for mult, results in multiples_loaded.items():\n", - " pool.submit_task(mult,\n", - " process_small_scalars,\n", - " results, selected_divisors)\n", - " for mult, future in tqdm(pool.as_completed(), leave=False, total=len(pool.tasks)):\n", - " prob_map = future.result()\n", + " pool.submit_task(fname,\n", + " load_chunk,\n", + " fname, selected_divisors)\n", + " for fname, future in tqdm(pool.as_completed(), leave=False, total=len(pool.tasks), smoothing=0):\n", + " if error := future.exception():\n", + " print(f\"Error {fname}, {error}\")\n", + " continue\n", + " new_distrs = future.result()\n", + " for mult, prob_map in new_distrs.items():\n", " if mult in distributions_mults:\n", " distributions_mults[mult].merge(prob_map)\n", " else:\n", " distributions_mults[mult] = prob_map\n", - " del multiples_loaded\n", - " gc.collect()" - ] - }, - { - "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", - "fig = plt.figure(figsize=(58, 12))\n", - "ax = plt.subplot(111)\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", - " y_values = [distributions_mults[mult][l] for l in plot_divisors]\n", - " vals[i,] = y_values\n", - " ax.plot(list(range(L)), y_values, color=colors[mult], linestyle=styles[mult], label=str(mult))\n", - " ax.set_title(divisor_name + \"\\nSamples: \" + str(distributions_mults[mult].samples))\n", - "\n", - "var = np.var(vals, axis=0)\n", - "#ax.plot(list(range(L)), var / np.max(var), label=\"cross-mult variance (normalized)\", ls=\"--\", lw=2, color=\"black\")\n", - "\n", - "ax.set_xlabel(\"divisors\") \n", - "ax.set_ylabel(\"error probability\")\n", - "ax.set_xticks(list(range(L)), plot_divisors, rotation=90)\n", - "\n", - "ax.grid()\n", - "plt.tight_layout()\n", - "box = ax.get_position()\n", - "ax.set_position([box.x0, box.y0, box.width * 0.9, box.height])\n", - "\n", - "# Put a legend to the right of the current axis\n", - "ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))\n", - "plt.show()\n", - "fig.savefig(f\"graphs/{divisor_name}.png\",dpi=300);" + "# Save\n", + "with open(f\"{divisor_name}_distrs.pickle\", \"wb\") as f:\n", + " pickle.dump(distributions_mults, f)" ] }, { "cell_type": "code", "execution_count": null, - "id": "8454cb7a-5308-43c6-9cd0-5de7946ec72a", + "id": "19d986ab-5fe7-4dd6-b5b5-4e75307217d6", "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)" + "# Optionally, load\n", + "with open(f\"{divisor_name}_distrs.pickle\", \"rb\") as f:\n", + " distributions_mults = pickle.load(f)" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "90a654f0-accc-4bb9-be2d-5f03e2d1e543", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ] - }, - { - "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": "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", + "cell_type": "markdown", + "id": "ef5b7a43-74b4-4e72-a3a1-955e175f5297", "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() " + "Now, go over all the divisor sets and visualize them (without the combs) into PNGs in the graphs/ directory." ] }, { "cell_type": "code", "execution_count": null, - "id": "0da0eed4-a5dc-4dde-9bd1-8b519d02375e", + "id": "906b5d78-b3a4-4cbb-8051-092d411ba735", "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", + "for divisor_name in divisor_map:\n", + " plot_mults = [mult.with_countermeasure(cm) for mult in selected_mults for cm in (None, \"gsr\", \"additive\", \"multiplicative\", \"euclidean\") if mult.klass not in (BGMWMultiplier, CombMultiplier)]\n", + " print(divisor_name)\n", + " plot_divisors = sorted(divisor_map[divisor_name])\n", + " L = len(plot_divisors)\n", + " N = len(plot_mults)\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)" + " fig = plt.figure(figsize=(L/4+10, 24))\n", + " ax = plt.subplot(111)\n", + " \n", + " vals = np.zeros((N, L))\n", + " n_samples = 0\n", + " for i, mult in enumerate(plot_mults):\n", + " y_values = [distributions_mults[mult][l] for l in plot_divisors]\n", + " vals[i,] = y_values\n", + " ax.plot(list(range(L)), y_values, color=colors[mult], linestyle=styles[mult], marker=markers[mult], label=str(mult))\n", + " n_samples += distributions_mults[mult].samples\n", + " \n", + " ax.set_title(divisor_name + \"\\nSamples(avg): \" + str(n_samples//N))\n", + " \n", + " var = np.var(vals, axis=0)\n", + " ax.plot(list(range(L)), var / np.max(var), label=\"cross-mult variance (normalized)\", ls=\"--\", lw=2, color=\"black\")\n", + " \n", + " ax.set_xlabel(\"divisors\") \n", + " ax.set_ylabel(\"error probability\")\n", + " ax.set_xticks(list(range(L)), plot_divisors, rotation=90)\n", + " \n", + " ax.grid()\n", + " plt.tight_layout()\n", + " box = ax.get_position()\n", + " ax.set_position([box.x0, box.y0, box.width * 0.9, box.height])\n", + " \n", + " ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), prop={'size': 6})\n", + " plt.close()\n", + " fig.savefig(f\"graphs/{divisor_name}_nocomb.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", + "id": "df2e236a-4540-4677-a7f1-563c4cc37a3e", "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)" + "Below you can choose a concrete divisor set and visualize it with all the mults, or just some to your liking." ] }, { "cell_type": "code", "execution_count": null, - "id": "1f403fa3-880d-45a8-aaf3-964b0fbc38d7", + "id": "b464865d-b169-446e-a9e7-0cead699aee1", "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", + "divisor_name = \"powers_of_2_large_3\"\n", + "plot_mults = [mult.with_countermeasure(cm) for mult in selected_mults for cm in (None, \"gsr\", \"additive\", \"multiplicative\", \"euclidean\")]\n", + "plot_divisors = sorted(divisor_map[divisor_name])#[-200:]\n", + "L = len(plot_divisors)\n", + "N = len(plot_mults)\n", "\n", - "fig = plt.subplots(figsize =(10, 4)) \n", + "fig = plt.figure(figsize=(L/4+5, 24))\n", + "ax = plt.subplot(111)\n", "\n", - "L = len(selected_divisors)\n", + "vals = np.zeros((N, L))\n", + "n_samples = 0\n", + "for i, mult in enumerate(plot_mults):\n", + " y_values = [distributions_mults[mult][l] for l in plot_divisors]\n", + " vals[i,] = y_values\n", + " ax.plot(list(range(L)), y_values, color=colors[mult], linestyle=styles[mult], marker=markers[mult], label=str(mult))\n", + " n_samples += distributions_mults[mult].samples\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", + "ax.set_title(divisor_name + \"\\nSamples(avg): \" + str(n_samples//N))\n", "\n", + "var = np.var(vals, axis=0)\n", + "ax.plot(list(range(L)), var / np.max(var), label=\"cross-mult variance (normalized)\", ls=\"--\", lw=2, color=\"black\")\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", + "ax.set_xlabel(\"divisors\") \n", + "ax.set_ylabel(\"error probability\")\n", + "ax.set_xticks(list(range(L)), plot_divisors, rotation=90)\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", + "ax.grid()\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", + "box = ax.get_position()\n", + "ax.set_position([box.x0, box.y0, box.width * 0.9, box.height])\n", "\n", - "plt.legend()\n", - "plt.show() \n", - "fig[0].savefig(f\"graphs/re.png\",dpi=300)" + "# Put a legend to the right of the current axis\n", + "ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), prop={'size': 5})\n", + "plt.show()\n", + "fig.savefig(f\"graphs/{divisor_name}.png\",dpi=300);" ] }, { "cell_type": "code", "execution_count": null, - "id": "24adaa81-df58-47a9-bdea-0b373be4368a", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae10629c-72f7-4a66-8495-8302ffa61887", + "id": "1b9f5231-b168-4ddf-89a2-53f975788e09", "metadata": {}, "outputs": [], "source": [] |
